{"record":{"id":"1ff3d3f80b6e4f91","repo":"JuliusBrussee/caveman","slug":"cave-subagent-input-limit","errorCode":"cave_subagent_input_limit","errorMessage":"cave_subagent_input_limit","messagePattern":"cave_subagent_input_limit","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/runtime.ts","lineNumber":3872,"sourceCode":"\nasync function executeSubagent(\n  toolDefinition: ToolDefinition,\n  params: unknown,\n  signal: AbortSignal | undefined,\n  parentOptions: InternalRunOptions,\n  usage: NestedUsage,\n  executionContext: InternalExecutionContext,\n  parentMeter: BudgetMeter | undefined,\n  parentDeadlineAt: number | undefined,\n): Promise<unknown> {\n  const runtime = toolDefinition.runtime;\n  if (runtime?.kind !== \"subagent\") throw new Error(\"cave_subagent_runtime_missing\");\n  if (params === null || typeof params !== \"object\" || Array.isArray(params) ||\n      typeof (params as { task?: unknown }).task !== \"string\") {\n    throw new Error(\"cave_subagent_arguments_invalid\");\n  }\n  const task = (params as { task: string }).task;\n  if (task.length > runtime.maxInputChars) throw new Error(\"cave_subagent_input_limit\");\n  const calls = usage.calls.get(toolDefinition.name) ?? 0;\n  if (calls >= runtime.maxCalls) throw new Error(\"cave_subagent_call_budget\");\n  // Reserve synchronously before any await so parallel Pi tool dispatch cannot\n  // pass the same maxCalls check twice.\n  usage.calls.set(toolDefinition.name, calls + 1);\n  const depth = executionContext.depth;\n  const depthLimit = Math.min(\n    parentOptions.maxSubagentDepth ?? DEFAULT_SUBAGENT_DEPTH_LIMIT,\n    ABSOLUTE_SUBAGENT_DEPTH_LIMIT,\n  );\n  if (depth + 1 > depthLimit) throw new Error(\"cave_subagent_depth_limit\");\n  // The wallet is carved here, still synchronously, for the same reason: two\n  // subagents dispatched in one turn must not both be funded out of the same\n  // remaining budget.\n  const walletAmount = parentMeter === undefined\n    ? undefined\n    : parentMeter.denomination === \"usd\" ? runtime.maxCostUsd : runtime.maxTokens;\n  if (parentMeter !== undefined && walletAmount === undefined) {","sourceCodeStart":3854,"sourceCodeEnd":3890,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/766dce6b1394ebb56a3090748d5a0240a5aefb36/packages/agent/src/runtime.ts#L3854-L3890","documentation":"A subagent task string longer than the tool runtime's maxInputChars cap throws cave_subagent_input_limit. The check runs before admission and budgeting, so an oversized prompt is rejected at zero cost.","triggerScenarios":"Inlining an entire document, codebase excerpt, or accumulated transcript into the task field; the model echoing large context into the subagent prompt; task.length exceeding runtime.maxInputChars.","commonSituations":"Delegating \"summarize this file\" by pasting the file instead of passing a path; tasks built by concatenating prior tool outputs; maxInputChars set low for cost control.","solutions":["Pass references (file paths, URLs, retrieval handles) instead of inlining content into task","Shorten or summarize the task before dispatch","Raise runtime.maxInputChars on the subagent tool definition if the budget allows"],"exampleFix":"// before\ntask: `Summarize this file:\\n${await readFile(\"big.md\", \"utf8\")}`\n\n// after\ntask: \"Read big.md in this repo and summarize it.\"","handlingStrategy":"validation","validationCode":"const MAX = tool.runtime.maxInputChars;\nif (task.length > MAX) {\n  throw new Error(`task is ${task.length} chars (max ${MAX}) — pass file paths or references, not content`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always delegate by reference (paths, URLs, handles) instead of pasting content","Trim or summarize long task text before dispatch","Set maxInputChars to match what your prompts actually produce, then enforce it"],"tags":["subagents","input-limits"],"backgroundTag":"input-size-limit-exceeded","analyzedSha":"766dce6b1394ebb56a3090748d5a0240a5aefb36","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}