coleam00/Archon · warning

Invalid JSON in request body

Error message

Invalid JSON in request body

What it means

The conversation-message route expected a JSON body ({ message: string }) but c.req.json() threw because the body is not valid JSON. The server logs message.json_parse_failed with the parse error and conversationId, then returns 400 with this message, indicating a malformed client request rather than a server fault.

Source

Thrown at packages/server/src/routes/api.ts:2928

      }

      const fileEntries = fileList.filter((e): e is File => e instanceof File);
      if (fileEntries.length > 0) {
        const result = await persistUploadedFiles(conversationId, fileEntries);
        if (!result.ok) {
          return c.json({ error: result.error }, result.status);
        }
        savedFiles = result.savedFiles;
        uploadDir = result.uploadDir;
        getLog().info({ conversationId, fileCount: savedFiles.length }, 'message.files_uploaded');
      }
    } else {
      let body: { message?: unknown };
      try {
        body = await c.req.json();
      } catch (parseErr: unknown) {
        getLog().warn({ err: parseErr, conversationId }, 'message.json_parse_failed');
        return c.json({ error: 'Invalid JSON in request body' }, 400);
      }

      if (typeof body.message !== 'string' || !body.message) {
        return c.json({ error: 'message must be a non-empty string' }, 400);
      }
      message = body.message;
    }

    // Look up conversation for message persistence
    let conv: Awaited<ReturnType<typeof conversationDb.findConversationByPlatformId>> = null;
    try {
      conv = await conversationDb.findConversationByPlatformId(conversationId);
    } catch (e: unknown) {
      getLog().error({ err: e, conversationId }, 'conversation_lookup_failed');
    }

    // Persist user message and pass DB ID to adapter for assistant message persistence
    if (conv) {

View on GitHub (pinned to 0773b97458)

Solutions

  1. JSON.stringify the payload object and send it as the body with Content-Type: application/json.
  2. Validate the body parses locally (JSON.parse in a test) before sending.
  3. Check for body truncation through proxies/timeouts on large messages.
  4. If the payload includes files, switch to the multipart variant of the route instead of embedding binary data in JSON.

Example fix

// before
await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: `{ message: "${msg}" }` });
// after
await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: msg }) });
Defensive patterns

Strategy: validation

Validate before calling

function buildMessageBody(message: string): string {
  if (typeof message !== 'string' || !message) throw new Error('message must be a non-empty string');
  return JSON.stringify({ message }); // validate locally what the route expects
}
const body = buildMessageBody(msg); // JSON.parse(body) round-trips safely

Type guard

function isValidMessageBody(raw: string): boolean {
  try {
    const parsed: unknown = JSON.parse(raw);
    return typeof (parsed as { message?: unknown })?.message === 'string' && (parsed as { message: string }).message.length > 0;
  } catch { return false; }
}

Try / catch

try {
  const res = await sendMessage(body);
  if (res.status === 400) {
    const { error } = await res.json();
    if (error === 'Invalid JSON in request body') throw new Error('Client sent non-JSON body; check JSON.stringify/content-type');
  }
} catch (err) { /* surface client-side serialization bug */ }

Prevention

When it happens

Trigger: POSTing to the conversation message endpoint with Content-Type application/json but a body that is empty, truncated, or invalid JSON (unquoted keys, trailing commas, plain text, binary data).

Common situations: Client sending form-encoded or raw-text body while claiming JSON content type; a proxy/CDN truncating the body; string-template code building JSON without escaping; forgetting JSON.stringify on the payload.

Understand the failure class

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/434554c877397da6. Report an issue: GitHub.