{"record":{"id":"a5ce8e3c01457d3c","repo":"JuliusBrussee/caveman","slug":"cave-claude-terminal-result-subtype-missing","errorCode":"cave_claude_terminal_${result?.subtype ?? \"missing\"}","errorMessage":"the Claude Agent SDK ended with ${result?.subtype ?? \"no result\"}","messagePattern":"the Claude Agent SDK ended with (.+?)","errorType":"error_code","errorClass":"CavemanRunError","httpStatus":null,"severity":"error","filePath":"packages/agent/src/claude-runtime.ts","lineNumber":324,"sourceCode":"        cacheWriteTokens: usage.cacheWriteTokens,\n        reasoningTokens: 0,\n        estimatedUsd: usage.catalogCostUsd,\n        unpriced: !usage.priced,\n        usageBasis: \"provider_reported\",\n        clampedOutputTokens: undefined,\n      });\n    }\n    for (const name of toolCalls) receipt.recordToolCall(name);\n    const carry = (code: string, message: string): CavemanRunError =>\n      new CavemanRunError(code, message, receipt.build({\n        runId: runID,\n        agentId: definition.id,\n        stopReason: \"complete\",\n        meter: undefined,\n      }));\n\n    if (result === undefined || result.subtype !== \"success\" || result.is_error) {\n      throw carry(\n        `cave_claude_terminal_${result?.subtype ?? \"missing\"}`,\n        `the Claude Agent SDK ended with ${result?.subtype ?? \"no result\"}`,\n      );\n    }\n    if (assistantModel !== undefined && normalizeClaudeModel(assistantModel) !== selected) {\n      throw carry(\n        \"cave_provider_model_identity_mismatch\",\n        `expected ${selected}, the SDK answered as ${assistantModel}`,\n      );\n    }\n    const text = result.result;\n    if (definition.output?.schema !== undefined) {\n      let parsed: unknown;\n      try {\n        parsed = result.structured_output ?? JSON.parse(text);\n      } catch {\n        throw carry(\"cave_output_schema_invalid_json\", \"the SDK output was not valid JSON\");\n      }","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/claude-runtime.ts#L306-L342","documentation":"runClaudeAgentWithOptions treats any Claude Agent SDK result that is missing, has subtype !== 'success', or has is_error=true as a terminal failure. It throws a carry() error with code `cave_claude_terminal_<subtype>` (or `_missing`) and this message naming the actual subtype.","triggerScenarios":"The SDK run finishes with subtype values like 'error_max_turns', 'error_during_execution', or returns undefined result; or returns success with is_error=true. Surfaced to callers of runClaudeAgent/runClaudeAgentInternal.","commonSituations":"Hitting the max-turns limit on long agentic tasks; the underlying Claude CLI crashing or being killed; invalid model name or auth failure causing the run to abort; SDK version mismatch changing the result shape.","solutions":["Read the error code suffix for the actual subtype (e.g. error_max_turns) and raise maxTurns/permission settings if that is the cause","Re-run with verbose logging to capture the SDK's failure detail (auth, model, tool errors)","Verify Claude CLI authentication (`claude` runs standalone) and that the selected model name is valid","Pin/upgrade the Claude Agent SDK so result shape matches what this runtime expects"],"exampleFix":"// before\nrunClaudeAgent({ prompt, maxTurns: 3 }) // hits error_max_turns\n// after\nrunClaudeAgent({ prompt, maxTurns: 30, allowedTools: [...] })","handlingStrategy":"retry","validationCode":"// pre-flight: confirm SDK auth and model before the run\nif (!isSupportedClaudeModel(selected)) throw new Error(`unsupported model: ${selected}`)","typeGuard":"function isSDKSuccess(r: unknown): r is { subtype: 'success'; is_error: false } {\n  return typeof r === 'object' && r !== null &&\n    (r as any).subtype === 'success' && (r as any).is_error === false\n}","tryCatchPattern":"try {\n  await runClaudeAgent(opts)\n} catch (err) {\n  const m = /cave_claude_terminal_(.+)/.exec(err.code ?? '')\n  if (m?.[1] === 'error_max_turns') { /* retry with higher maxTurns */ }\n  else { /* surface auth/model failure */ }\n}","preventionTips":["Set generous maxTurns for long agentic tasks","Verify Claude CLI auth and model availability before launching the agent","Pin the Claude Agent SDK version and review its result-shape changelog on upgrades","Retry transient subtypes only; treat auth/model errors as non-retryable"],"tags":["agent","sdk","runtime"],"backgroundTag":"upstream-api-error","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}