[DEV-100] Story creation fails with 'Failed to parse story from agent output' when the agent's response isn't clean JSON - #93
Merged
Conversation
…story from agent output' when the agent's response isn't clean JSON
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Task: DEV-100
Summary: Story creation fails with 'Failed to parse story from agent output' when the agent's response isn't clean JSON
Implementation Details
The log file doesn't exist on disk, so I'll work from the error signature ("Expected double-quoted property name at position 4705") and the code paths. Let me find the caller and tests.
The evidence log is gone, so let me check for any copies/fixtures and look at the debug-dump helper plus validation shapes used by generateStory.
I now have the full picture. The evidence log is gone, so I'll target the error class from the signature. Two directions per the AC: extend the repair passes in
agent-json.ts, make parse failures friendlier/actionable, and consider a bounded auto-retry at the engine layer. Let me look at the remaining touchpoints.The evidence log is gone, so I'll work from the error signature itself. First, let me empirically pin down which malformed-output shapes produce exactly this V8 error ("Expected double-quoted property name in JSON") — that tells me which repair pass is missing.
The error wording is JavaScriptCore-flavored ("double-quoted"), meaning it was raised under Bun (
bun run). Let me reproduce candidate shapes under Bun instead of Node.Bun/JSC and modern Node wordings differ from the reported error — it matches older V8 (Electron/V8 family), thrown wherever a property name was expected: unquoted keys, comments before members, trailing commas, single/smart-quoted keys, or quote-desync from unescaped quotes inside rich descriptions. Since the log is unrecoverable, my plan covers that whole class. Let me check the remaining call sites before implementing.
Analysis complete. The error is the older-V8/JSC "expected property name" class — produced by unquoted/commented/smart-or-single-quoted keys, trailing commas, or string-state desync from unescaped quotes in rich descriptions; existing passes don't cover those. Plan: extend repair passes, wrap errors friendlily, add one auto-retry, and polish user-facing copy.
Now the core parser extension:
Let me clean up two sloppy spots in the new pass and validate against the failing shapes:
Now validate both regression shapes and the new ones:
Found it — a bug in my
escapeUnescapedQuotesInStringsrewrite:text.indexOf(nextChar)scans from the wrong offset. Let me fix the helper to use absolute indices:The prose-quoted-term case (
Pick "one", then "two") defeats both quote heuristics since commas follow the quoted words. Deterministic salvage for that class: reconstruct the payload from known schema keys (summary/description/subtasks) by slicing raw regions and re-serializing viaJSON.stringify. Adding it as a last-resort candidate builder:Now wire the salvage candidate into the base list:
Parser hardened. Now the engine layer — friendly parse errors plus the one-shot auto-retry:
Now the retry in
runAndParse:That draft has two flaws: it discards the second attempt's raw result (forcing a third agent call for the dump) and drops the
agent-faileddump label. Rewriting cleanly:Now update the CLI copy and chat message text:
Now update and extend the test files:
Salvage ordering bug: trailing comma must be stripped before the closing quote. Fixing:
Parser suite green. Now add engine-level retry tests and align the chat copy test:
Workspace deps need linking:
All 338 pm tests pass. Now the docs FAQ entry, then lint/typecheck:
pm enables
noUncheckedIndexedAccess, so indexed access needs guards. Let me get the full error list and fix:Touched files are lint-clean. Now format and run the full monorepo verification:
Full monorepo green: format 11/11, typecheck 11/11, all tests pass (pm: 338). Final smoke test — simulate the exact DEV-100 failure class end-to-end through the engine path:
DEV-100 implemented. The evidence log (
/tmp/devpm-story-generation-parse-1787827025444.log) no longer exists, so I worked from the error signature — the older-V8/JSC "Expected double-quoted property name in JSON" class, thrown wherever a property name was expected: unquoted/single/smart-quoted keys,//comments, trailing commas, or string-state desync from unescaped quotes in long rich descriptions.Changes
packages/pm/lib/agent-json.ts— new repair passes layered onto the existing variant matrix (existing behavior/order preserved first):") normalization{summary, description, subtasks}from raw value regions and re-serializes viaJSON.stringify— recovers outputs whose inner prose quotes defeat every heuristicrunAndParsegives malformed output exactly one corrective re-run with a strict-JSON reminder appended to the same prompt; exhaustion dumps the final attempt (devpm-<step>-parse-*.log) with the errorextractJsonPayloadheadlines "malformed output… Retry the generation, or try another harness/model" (parser detail demoted); CLI paths print the message + log path; chatrenderErrorincludes the dump pathVerification: 338/338 pm tests pass; repo-wide format, typecheck, and tests all green (11/11 packages).
This PR was automatically created by @devintern/code