Skip to content

feat(compat): salvage JSON-string submit payloads before failing schema validation (#185)#201

Merged
OGtwelve merged 1 commit into
mainfrom
fix/salvage-json-submit-185
Jul 14, 2026
Merged

feat(compat): salvage JSON-string submit payloads before failing schema validation (#185)#201
OGtwelve merged 1 commit into
mainfrom
fix/salvage-json-submit-185

Conversation

@OGtwelve

@OGtwelve OGtwelve commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Closes #185. XS P1 batch from the parity verification (#196).

Problem

Weak models frequently call the terminal submit tool with a JSON string (often markdown-fenced) instead of the object the schema wants. Live evidence (qwen/qwen3-coder:free): planner + worker + verify gate passed, two commits landed — then PR composition failed schema validation 3× (expected object, received string) and the group blocked at pr-open, one step from success.

Fix

submittedOutput, on a failed validation of a string payload, strips a single ```-fence and JSON.parses it, then re-validates: success is accepted as if the object had been submitted directly. Runs upstream of the #101 retry kernel, so retries only spend on genuinely wrong shapes. A non-string, non-parsing, or still-invalid value keeps the existing typed `invalid` result (with the parsed value's issues when it parsed but didn't validate). Zero cost to well-behaved models; provider-agnostic (no model sniffing).

Tests

  • stringified-valid + fenced-valid salvage to ok; stringified-but-schema-invalid stays invalid with the parsed-object issues; non-JSON string and object paths unchanged.
  • Green: typecheck (both) + test:node (compat 258) + biome.

Part of #196.

Summary by CodeRabbit

  • Bug Fixes
    • Improved submitted output handling when tool input is provided as a JSON string.
    • Added support for JSON wrapped in fenced code blocks.
    • Valid JSON strings are now correctly parsed and validated against the expected schema.
    • Invalid parsed values now report validation issues against the parsed content.

…ma validation (#185)

Weak models frequently call the terminal submit tool with a JSON STRING (often
markdown-fenced) instead of the object the schema wants. Live evidence
(qwen/qwen3-coder:free): planner + worker + verify gate passed, two commits
landed — then PR composition failed schema validation 3x ('expected object,
received string') and the group blocked at pr-open, one step from success.

submittedOutput now, on a failed validation of a STRING payload, strips a single
```-fence and JSON.parses it, then re-validates: success is accepted as if the
object had been submitted directly. This runs upstream of the #101 retry kernel,
so retries only spend on genuinely wrong shapes. A non-string, non-parsing, or
still-invalid value keeps the existing typed `invalid` result (with the parsed
value's issues when it parsed but didn't validate). Zero cost to well-behaved
models; provider-agnostic (no model sniffing).

Tests: stringified-valid + fenced-valid salvage to ok; stringified-but-schema-
invalid stays invalid with the parsed-object issues; non-JSON string and object
paths unchanged.

Part of #196.
@OGtwelve

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.


You're currently rate limited under our Fair Usage Limits Policy. Your recent PR review activity is in the 95th percentile or higher among CodeRabbit users, so adaptive limits apply. Your next review will be available in 46 minutes.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 9f789c12-7a8c-4986-92bd-64377142072c

📥 Commits

Reviewing files that changed from the base of the PR and between 277c344 and a15e36d.

📒 Files selected for processing (2)
  • packages/ai-claude-compat/src/subagent.test.ts
  • packages/ai-claude-compat/src/subagent.ts

📝 Walkthrough

Walkthrough

submittedOutput now salvages stringified or fenced JSON submit payloads, revalidates parsed values against the schema, and reports parsed validation issues when necessary. Tests cover valid and invalid cases.

Changes

JSON submit payload salvage

Layer / File(s) Summary
Salvage and revalidate submit inputs
packages/ai-claude-compat/src/subagent.ts
submittedOutput parses string inputs, tolerates a single fenced JSON wrapper, and revalidates parsed values while preserving existing behavior for non-string or unparsable inputs.
Validate recovered payload behavior
packages/ai-claude-compat/src/subagent.test.ts
Tests cover valid stringified JSON, fenced JSON, and parsed payloads that fail schema validation.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SubmitToolCall
  participant submittedOutput
  participant salvageJsonString
  participant outputSchema
  SubmitToolCall->>submittedOutput: Provide call.input
  submittedOutput->>outputSchema: Validate original input
  outputSchema-->>submittedOutput: Return validation failure
  submittedOutput->>salvageJsonString: Parse string or fenced JSON
  salvageJsonString-->>submittedOutput: Return parsed value
  submittedOutput->>outputSchema: Validate parsed value
  outputSchema-->>submittedOutput: Return typed result or parsed issues
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: salvaging JSON-string submit payloads before schema validation fails.
Linked Issues check ✅ Passed The implementation and tests align with #185 by accepting valid JSON strings, fenced JSON, and preserving invalid behavior otherwise.
Out of Scope Changes check ✅ Passed The changes stay focused on the linked compatibility fix and its tests, with no obvious unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/salvage-json-submit-185

Comment @coderabbitai help to get the list of available commands.

@OGtwelve

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@OGtwelve OGtwelve merged commit 2ded342 into main Jul 14, 2026
4 checks passed
@OGtwelve OGtwelve deleted the fix/salvage-json-submit-185 branch July 14, 2026 08:38
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.

feat(compat): salvage JSON-string submit payloads before failing schema validation

1 participant