You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix the code-generation job so that a Groq json_validate_failed error is detected, logged, and correctly falls through to the Anthropic provider instead of crashing the run.
Still missing:err.code = 'json_validate_failed' in groq_client.mjs, the per-provider log in llm_client.mjs, and both unit tests. generate_issue_change.mjs still uses the default response_format: json_object, so the error can still happen.
When Groq's JSON mode cannot constrain a large structured output (large file_content strings in the changes array), it returns HTTP 400 with code: "json_validate_failed". The pipeline crashes with:
Root cause:classifyError('400') in error_taxonomy.mjs returns 'UNKNOWN' (400 is not in the PERMANENT or TRANSIENT lists). In groq_client.mjs, retryable is false for 400 so no retry happens. In llm_client.mjs, UNKNOWN does not trigger a break, so the loop should continue to Anthropic — but the final error message only reports the Groq failure, indicating the Anthropic fallback also fails silently without surfacing its own error clearly.
🔁 Steps to reproduce
Trigger the code-generation workflow on an issue requiring multi-file changes (≥ 3 large files).
Observe the Groq provider returning HTTP 400 with json_validate_failed.
The job exits with code 1 — "All providers failed".
When Groq returns json_validate_failed, the system:
Immediately stops retrying Groq (already the case — retryable: false).
Logs the Groq failure with its error code for traceability.
Falls through to Anthropic and succeeds (or reports the Anthropic failure clearly if it also fails).
🧪 Acceptance criteria
When Groq returns HTTP 400 with code: "json_validate_failed", groq_client.mjs attaches err.code = 'json_validate_failed' to the thrown error so downstream handlers can inspect it.
llm_client.mjs logs { provider: 'groq', error_type: 'json_validate_failed', status: 400 } before moving to the next provider.
When Groq fails with json_validate_failed and Anthropic also fails, the error message includes both failures (e.g. "All providers failed: groq: ..., anthropic: ...") so the actual Anthropic error is visible. (Already the case on main: callLLM lists every provider error.)
Unit test in scripts/tests/groq_client.test.mjs: a mocked 400 response with json_validate_failed body results in an error with err.code === 'json_validate_failed' and err.retryable === false.
⚠️ Constraints
Do not change the retry behavior for other 400 errors (e.g. malformed payloads unrelated to JSON mode).
The PERMANENT break in llm_client.mjs stops all providers — do not reclassify json_validate_failed as PERMANENT; the fallback to Anthropic must remain active.
Backward compatible: existing error handling for 401, 403, 429, 5xx must be unaffected.
🎯 Goal
Fix the
code-generationjob so that a Groqjson_validate_failederror is detected, logged, and correctly falls through to the Anthropic provider instead of crashing the run.📍 Context
scripts/lib/groq_client.mjs,scripts/lib/error_taxonomy.mjs,scripts/lib/llm_client.mjscode-generationjob🔗 Status (re-checked 2026-10-01 on
main@ 4e499fb)apiKey,apiUrlandmodel, so it POSTs to Groq's endpoint and fails with 401. A mocked unit test for criterion 3 would pass anyway, because the mocked fetch accepts any key and URL. Write that test against the per-provider config introduced by [BUG] callLLM provider fallback sends the primary provider's model, API key and URL to the fallback provider #162 (assert URL, auth header and model).callLLMnow pushes every provider's error intoAll providers failed: …, so criterion 4 is already met. The real cause behind the missing/failed Anthropic fallback is [BUG] callLLM provider fallback sends the primary provider's model, API key and URL to the fallback provider #162.err.code = 'json_validate_failed'ingroq_client.mjs, the per-provider log inllm_client.mjs, and both unit tests.generate_issue_change.mjsstill uses the defaultresponse_format: json_object, so the error can still happen.scripts/tests/llm_client.test.mjs: do not generate both in parallel.❗ Observed problem
When Groq's JSON mode cannot constrain a large structured output (large
file_contentstrings in thechangesarray), it returns HTTP 400 withcode: "json_validate_failed". The pipeline crashes with:Root cause:
classifyError('400')inerror_taxonomy.mjsreturns'UNKNOWN'(400 is not in the PERMANENT or TRANSIENT lists). Ingroq_client.mjs,retryableisfalsefor 400 so no retry happens. Inllm_client.mjs,UNKNOWNdoes not trigger abreak, so the loop should continue to Anthropic — but the final error message only reports the Groq failure, indicating the Anthropic fallback also fails silently without surfacing its own error clearly.🔁 Steps to reproduce
code-generationworkflow on an issue requiring multi-file changes (≥ 3 large files).json_validate_failed.Example: run 26795257405, job 78990103447 (run ID
issue-134)✅ Expected behavior
When Groq returns
json_validate_failed, the system:retryable: false).🧪 Acceptance criteria
code: "json_validate_failed",groq_client.mjsattacheserr.code = 'json_validate_failed'to the thrown error so downstream handlers can inspect it.llm_client.mjslogs{ provider: 'groq', error_type: 'json_validate_failed', status: 400 }before moving to the next provider.json_validate_failedand Anthropic is available, thecallLLMfunction returns the Anthropic response successfully (no crash). Requires [BUG] callLLM provider fallback sends the primary provider's model, API key and URL to the fallback provider #162.json_validate_failedand Anthropic also fails, the error message includes both failures (e.g."All providers failed: groq: ..., anthropic: ...") so the actual Anthropic error is visible. (Already the case onmain:callLLMlists every provider error.)scripts/tests/llm_client.test.mjs: mocking Groq to throw ajson_validate_failed400 error verifies that Anthropic is called as fallback, with Anthropic's own URL, key and model (see [BUG] callLLM provider fallback sends the primary provider's model, API key and URL to the fallback provider #162).scripts/tests/groq_client.test.mjs: a mocked 400 response withjson_validate_failedbody results in an error witherr.code === 'json_validate_failed'anderr.retryable === false.PERMANENTbreak inllm_client.mjsstops all providers — do not reclassifyjson_validate_failedas PERMANENT; the fallback to Anthropic must remain active.