fix(frontend): only send JSON content-type when a body is present

Body-less POSTs (resume, close) sent content-type: application/json with no
body, so Fastify rejected them with FST_ERR_CTP_EMPTY_JSON_BODY (400) and
clicking an existing session never reopened it. apiFetch now adds the header
only when init.body is set.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-28 18:05:23 +02:00
co-authored by Claude Opus 4.8
parent 4e6d4a4cea
commit acb674b4bc
2 changed files with 37 additions and 4 deletions
+10 -4
View File
@@ -1,10 +1,16 @@
const BASE = import.meta.env.VITE_BACKEND_URL ?? "http://localhost:8787";
export async function apiFetch<T>(path: string, init?: RequestInit): Promise<T> {
const res = await fetch(`${BASE}${path}`, {
headers: { "content-type": "application/json" },
...init,
});
// Only declare a JSON content-type when we actually send a body. Body-less
// POSTs (resume, close) would otherwise make Fastify reject the empty body
// with FST_ERR_CTP_EMPTY_JSON_BODY (400).
const headers: Record<string, string> = {
...(init?.headers as Record<string, string> | undefined),
};
if (init?.body != null && !("content-type" in headers) && !("Content-Type" in headers)) {
headers["content-type"] = "application/json";
}
const res = await fetch(`${BASE}${path}`, { ...init, headers });
if (!res.ok) throw new Error(`${res.status} ${await res.text().catch(() => "")}`);
return res.status === 204 ? (undefined as T) : ((await res.json()) as T);
}