action: strip Content-Type on body-less apiFetch requests (#692) (#694)

* action: strip Content-Type on body-less apiFetch requests (#692)

Vercel's Next.js lambda adapter (Next 16.1.x) attempts to decode a
request body when Content-Type is set and throws
`SyntaxError: Unexpected end of data` before delegating to the route
handler, returning a 500. Hit /run-context exclusively because it was
the only body-less GET that sent `Content-Type: application/json`.

- Drop `Content-Type: application/json` from the GET in
  `action/utils/runContext.ts` (meaningless on a body-less request).
- Defensively strip any `content-type` header in `action/utils/apiFetch.ts`
  when no body is present so future callers can't reintroduce this.

* apiFetch: soften comment — empirical observation, RFC 9110 §8.3 framing
This commit is contained in:
Colin McDonnell
2026-05-13 02:03:24 +00:00
committed by pullfrog[bot]
parent d8f825034f
commit 43bb14bf87
2 changed files with 12 additions and 1 deletions
+12
View File
@@ -37,6 +37,18 @@ export async function apiFetch(options: ApiFetchOptions): Promise<Response> {
headers["x-vercel-protection-bypass"] = bypassSecret;
}
// never send Content-Type on body-less requests. empirically, Vercel's
// Next.js lambda adapter (Next 16.1.x) throws `SyntaxError: Unexpected
// end of data` before delegating to the route handler — returning a 500 —
// when Content-Type is set but no body is present. exact mechanism is
// unverified (minified runtime frame), but Content-Type on a body-less
// request has no defined semantics per RFC 9110 §8.3 anyway. see #692.
if (!options.body) {
for (const key of Object.keys(headers)) {
if (key.toLowerCase() === "content-type") delete headers[key];
}
}
log.debug(`api fetch: ${options.method ?? "GET"} ${url.pathname}`);
const init: RequestInit = {
-1
View File
@@ -88,7 +88,6 @@ export async function fetchRunContext(params: {
try {
const headers: Record<string, string> = {
Authorization: `Bearer ${params.token}`,
"Content-Type": "application/json",
};
if (params.oidcToken) {
headers["X-GitHub-OIDC-Token"] = params.oidcToken;