Skip to content

Accept native placeholders for blank Claude function results - #758

Draft
RGB-loop wants to merge 6 commits into
MiniMax-AI:mainfrom
RGB-loop:fix/claude-blank-function-result
Draft

RGB-loop wants to merge 6 commits into
MiniMax-AI:mainfrom
RGB-loop:fix/claude-blank-function-result

Conversation

@RGB-loop

@RGB-loop RGB-loop commented Oct 18, 2026 •

Copy link
Copy Markdown

Problem

The public contract lets a function result omit output and error or set them to null (contracts/agents-api/execution-tools.md). Core admits {"success":true,"output":""}, "output":[] and "error":"", and maps them to empty function result content. With the Claude Harness, those results fail the whole Turn with execution_failed.

The pinned native harness (@anthropic-ai/claude-agent-sdk 0.3.269) does not record a blank tool result as submitted:

submitted function result native tool_result content
success, [] / "" / whitespace only (mcp__functions__<name> completed with no output)
error, [] Unknown error
error, "" Command failed with no output
error, "x" + "", or "boom\n" joined text, trimmed (x, boom)

FunctionBridge.consume requires the native block to equal the submitted content, so it throws Native function response differs from submitted result. although the native harness did apply the result.

Change

Adapter code only; Core admission and the public contract are unchanged.

  • A result with no image and no non-blank text is confirmed by a native text tool_result with the same is_error. The native harness owns how it renders a blank result.
  • Error text is compared after the same join("\n").trim() the native formatter applies.
  • Every other result keeps exact matching, and an is_error mismatch still fails.
  • packages/claude-sdk-adapter/README.md (the bridge's owning doc) states both receipt rules.
  • The OpenAI compatibility ledger (contracts/agents-api/index.md, with the zh/ mirror and source_hash) records the model-visible difference: Claude Code shows its own placeholder for a blank result and trims error text.

Semantics and alternatives (CONTRIBUTING: raise semantics with a recommendation)

  1. This PR: accept the native placeholder by outcome for blank results. This keeps receipt confirmation for every result that has content and does not depend on the SDK's wording.
  2. Match the exact pinned placeholder strings. This is stricter, but it breaks on SDK pin upgrades and depends on the tool name. Not chosen.
  3. Reject blank function results at Core admission for the Claude profile. This would narrow the public contract because of an engine limitation. Not chosen.

Validation

  • packages/claude-sdk-adapter:
    • pnpm typecheck passes.
    • pnpm test passes (build plus all adapter tests).
    • The new function_bridge.test.mjs case covers six blank results (including a whitespace-only error) with the captured native strings. For each, a flipped is_error is rejected. It also covers trimmed error text (trailing empty part, trailing newline, leading space, leading empty part, empty part in the middle), and checks that non-blank success and error mismatches still throw.
    • On the baseline, the new test fails and the existing tests pass.
  • make check-names passes. git diff --check is clean.
  • The zh/index.md source_hash matches the new English ledger. Checked with an offline subset of website/tests/translations.test.mjs (source, hash, fences, list items, inline literals); the full website test was not run because its dependencies were not installed locally.
  • Fixture end to end, not live:
    • Setup: the built adapter (dist/main.js) with its pinned native SDK binary (linux-x64), against a local fake Anthropic Messages API on 127.0.0.1, with a temporary HOME/cwd and a fake key.
    • Each case answers one function call with the case's result. 13 cases: 4 controls, 5 blank results, and 4 padded/mixed text results.
    • In the implementer's own runs, the blank and trimmed-error cases ended in execution_failed before this change; after it, all 13 emit function_applied and reach result.
  • Independent review: a fresh subagent that received only the requirements, acceptance criteria, boundaries, repository path and base (no implementation summary) reviewed the complete diff against main and found no blocking issues, as AGENTS.md asks.
  • Not covered: the native harness also truncates error text longer than about 10,000 characters, and replaces oversized success output with a preview. Exact matching still rejects both. That predates this change and is left for a separate fix.
  • Live acceptance was not run. It lacks a prerequisite: we have no Anthropic provider account. So this change has not passed live Harness qualification. The fixture runs above check the native wire behavior with a synthetic model only.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

RGB-loop and others added 2 commits October 18, 2026 07:01
The pinned Claude harness replaces a function result without an image or
visible text with its own placeholder (for example "Unknown error"), and it
trims joined error text. The exact receipt check failed the Turn with
execution_failed for those results. Blank results are now confirmed by their
native outcome, and error text is compared after the same trim; other results
keep exact matching.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sults

The adapter README now states that a blank result is confirmed by its native
outcome and that error text is compared after the native join and trim. The
OpenAI compatibility ledger records the model-visible placeholder and trimmed
error text, with the Chinese mirror and source hash updated. The unit test
also covers whitespace-only errors and leading whitespace in error text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@RGB-loop
RGB-loop marked this pull request as ready for review October 18, 2026 09:37
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@RGB-loop
RGB-loop marked this pull request as draft October 18, 2026 13:14
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@RGB-loop
RGB-loop marked this pull request as ready for review October 18, 2026 14:01
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@RGB-loop
RGB-loop marked this pull request as draft October 19, 2026 12:55
…nction-result

# Conflicts:
#	contracts/agents-api/zh/index.md
#	packages/claude-sdk-adapter/README.md
#	packages/claude-sdk-adapter/tests/function_bridge.test.mjs

This branch has not been deployed

No deployments
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.

1 participant