🎯 Goal
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.
📍 Context
- Repo: autonomous-dev-loop
- Component:
scripts/lib/groq_client.mjs, scripts/lib/error_taxonomy.mjs, scripts/lib/llm_client.mjs
- Environment: GitHub Actions —
code-generation job
❗ Observed problem
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:
{"level":"error","msg":"Fatal error","error":"All providers failed: groq: Groq API HTTP error 400: {\"error\":{\"code\":\"json_validate_failed\",...}}"}
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".
Example: run 26795257405, job 78990103447 (run ID issue-134)
✅ Expected behavior
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
⚠️ 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❗ 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).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.scripts/tests/llm_client.test.mjs: mocking Groq to throw ajson_validate_failed400 error verifies that Anthropic is called as fallback.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.