Skip to content

fix: pass through a response that is JSON but not an object - #65

Draft
rickstaa wants to merge 1 commit into
mainfrom
fix/call-runner-json-array
Draft

fix: pass through a response that is JSON but not an object#65
rickstaa wants to merge 1 commit into
mainfrom
fix/call-runner-json-array

Conversation

@rickstaa

Copy link
Copy Markdown
Member

Closes #64.

call_runner picks its return path from Content-Type alone: JSON parses into result.data, anything else arrives unparsed in result.content. A body that is valid JSON but not an object matched neither. It took the JSON branch, failed isinstance(data, dict), and raised Live runner call expected JSON object, got list.

A runner that proxies somebody else's API does not choose its response shape, and a top-level array is a common one — every Hugging Face inference task except text-to-image answers with one. Such a runner could not be called through the SDK at all. The workaround was for the runner to stop advertising JSON so the body took the opaque-bytes path, which in runner-app-examples#82 meant nginx relabelling a JSON body as text/plain.

What changed

Non-object JSON is now handed back unparsed in result.content, exactly as an image or ndjson already is, with result.content_type left saying application/json so the caller knows what it is holding.

Objects keep today's behavior including session_id extraction, so the only path that behaves differently is the one that used to raise. Strictness stays where the body carries protocol fields: proxy create and trickle channel remove are untouched.

test_json_array_still_rejected becomes test_json_array_returns_raw, and a scalar case joins it, since the rule is about being an object rather than about arrays.

Testing

  • uv run --frozen --group test pytest — 245 passed.
  • The issue's repro returns data: {} content: b'[{"label": "llama", "score": 0.99}]' instead of raising.

@rickstaa
rickstaa requested a review from j0sh as a code owner August 18, 2026 10:31
call_runner picked its return path from Content-Type alone, so a body
that is valid JSON but not an object matched neither: it took the JSON
branch, failed the isinstance check, and raised. A runner proxying
somebody else's API does not choose its response shape, and a top-level
array is a common one, so it now comes back unparsed in `content` the
way an image or ndjson already does.

Objects are unchanged, session_id included, and the only path that
behaves differently is the one that used to raise. Strictness stays
where protocol fields are read out of the body: proxy create and
trickle channel remove.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@rickstaa
rickstaa force-pushed the fix/call-runner-json-array branch from 9cd3c07 to acb13b4 Compare August 18, 2026 10:36
@rickstaa
rickstaa marked this pull request as draft August 18, 2026 12:30
@rickstaa

Copy link
Copy Markdown
Member Author

@josh please ignore this was my agent testing things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

call_runner rejects a top-level JSON array, so a runner cannot pass one through

1 participant