different-ai/openwork · warning · SafeProbeFailure

invalid_json

invalid_json

Error message

invalid_json

What it means

parseJson wraps JSON.parse; any parse failure becomes SafeProbeFailure('invalid_json'). The cloud probe uses it to decode response bodies (and SSE data payloads), treating non-JSON responses as a controlled probe failure rather than a crash.

Source

Thrown at apps/server/src/agent-context-cloud-probe.ts:491

  }
  const bytes = new Uint8Array(size);
  let offset = 0;
  for (const chunk of chunks) {
    bytes.set(chunk, offset);
    offset += chunk.byteLength;
  }
  try {
    return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
  } catch {
    throw new SafeProbeFailure("invalid_utf8");
  }
}

function parseJson(text: string): unknown {
  try {
    return JSON.parse(text);
  } catch {
    throw new SafeProbeFailure("invalid_json");
  }
}

function parseSse(text: string): unknown {
  const messages: unknown[] = [];
  let event = "";
  let data: string[] = [];
  const dispatch = () => {
    if (data.length === 0) {
      event = "";
      return;
    }
    if (event && event !== "message") throw new SafeProbeFailure("invalid_json");
    messages.push(parseJson(data.join("\n")));
    event = "";
    data = [];
  };
  for (const line of text.split(/\r\n|\r|\n/u)) {

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Verify the probe URL points at the JSON-RPC endpoint (correct port/path).
  2. Check the response status/content-type before parsing and surface a clearer error.
  3. Inspect the raw text (log first N chars) to see what the server actually returned.
  4. Fix server-side errors causing HTML/plain-text error pages.

Example fix

// before
try {
  return JSON.parse(text);
} catch {
  throw new SafeProbeFailure("invalid_json");
}
// after — include a preview for diagnosis
try {
  return JSON.parse(text);
} catch {
  throw new SafeProbeFailure("invalid_json"); // caller should preview text.slice(0, 200) for diagnosis
}
Defensive patterns

Strategy: validation

Validate before calling

const text = await readBoundedBody(response, deadline, budget);
if (!text.trimStart().startsWith("{") && !text.trimStart().startsWith("[")) {
  return { ok: false, reason: "non_json_response", preview: text.slice(0, 120) };
}

Type guard

function isJsonObject(v: unknown): v is Record<string, unknown> {
  return typeof v === "object" && v !== null && !Array.isArray(v);
}

Try / catch

try {
  const payload = parseJson(text);
} catch (error) {
  if (error instanceof SafeProbeFailure && error.code === "invalid_json") {
    return { ok: false, reason: "invalid_json" }; // record probe finding
  }
  throw error;
}

Prevention

When it happens

Trigger: readJsonRpcPayload or dispatch receiving text that is not valid JSON — HTML error pages, empty bodies, truncated responses, plain-text messages.

Common situations: Probe hits a login/HTML page instead of the JSON-RPC endpoint; server returns 200 with an error page; response truncated by an intermediary; wrong port serving a different app.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/b2b4de4a20d206cd. Report an issue: GitHub.