abi/screenshot-to-code · warning · HTTPException
Invalid {side} JSON: {error.msg} (line {error.lineno}, colum
Error message
Invalid {side} JSON: {error.msg} (line {error.lineno}, column {error.colno}) What it means
400 raised by _load_openai_input_compare_payload in backend/routes/evals.py:181 when json.loads fails on the left_json or right_json body field of POST /openai-input-compare. The detail includes the exact JSONDecodeError message with line and column, so the syntax error location is identified precisely.
Source
Thrown at backend/routes/evals.py:181
left_summary: str
right_summary: str
left_value: object | None
right_value: object | None
class OpenAIInputCompareResponse(BaseModel):
common_prefix_items: int
left_item_count: int
right_item_count: int
difference: OpenAIInputCompareDifferenceResponse | None
formatted: str
def _load_openai_input_compare_payload(raw_json: str, side: str) -> object:
try:
payload = json.loads(raw_json)
except json.JSONDecodeError as error:
raise HTTPException(
status_code=400,
detail=(
f"Invalid {side} JSON: {error.msg} "
f"(line {error.lineno}, column {error.colno})"
),
)
try:
compare_openai_inputs(payload, payload)
except ValueError as error:
raise HTTPException(status_code=400, detail=f"Invalid {side} payload: {error}")
return payload
@router.post("/openai-input-compare", response_model=OpenAIInputCompareResponse)
async def compare_openai_inputs_for_evals(
request: OpenAIInputCompareRequest,View on GitHub (pinned to d026163f58)
Solutions
- Use the reported line/column from the detail to fix the syntax error.
- Validate both strings with JSON.parse in the client before sending.
- Re-export the original payload from the log file unmodified instead of hand-editing.
Example fix
// before
body: JSON.stringify({ left_json: leftTextarea.value, right_json: rightTextarea.value })
// after
const left = JSON.parse(leftTextarea.value); // throws early with position info
const right = JSON.parse(rightTextarea.value);
body: JSON.stringify({ left_json: leftTextarea.value, right_json: rightTextarea.value }) Defensive patterns
Strategy: validation
Validate before calling
function assertJson(text: string, label: string) {
try { JSON.parse(text); } catch (e) {
throw new Error(`Invalid ${label} JSON: ${(e as Error).message}`);
}
}
assertJson(leftJson, 'left');
assertJson(rightJson, 'right'); Try / catch
const res = await fetch('/openai-input-compare', ...);
if (res.status === 400) { /* detail has line/column; jump editor to it */ } Prevention
- Parse both sides client-side before posting.
- Feed payloads from unmodified log exports, not hand-edited text.
When it happens
Trigger: POST /openai-input-compare with a body where left_json or right_json is not valid JSON — trailing commas, unescaped quotes, single-quoted strings, truncated payloads from copy-paste of captured LLM request bodies.
Common situations: Diffing logged OpenAI request payloads that were truncated by log rotation or manually edited; pasting JSON wrapped in smart quotes from a rich-text source.
Related errors
- Invalid {side} payload: {error}
- Invalid run id
- max_age_days must be >= 1
- Design system name is required
- Invalid eval set name: {set_name!r}
AI-assisted analysis of abi/screenshot-to-code@d026163f58 (2026-08-14).
Data as JSON: /api/errors/84a66a5be69c2c47.
Report an issue: GitHub.