JuliusBrussee/caveman · error
cave_subagent_input_limit
cave_subagent_input_limit
Error message
cave_subagent_input_limit
What it means
The runtime caps the character length of the task prompt handed to a subagent at runtime.maxInputChars. A task string longer than this configured limit throws cave_subagent_input_limit, protecting the child agent's context window and cost from oversized inputs.
Solutions
- Shorten the task: reference files/paths by name instead of embedding their contents
- Increase runtime.maxInputChars in the subagent runtime configuration if large inputs are legitimate
- Split the work into multiple smaller subagent tasks
- Pre-truncate or summarize the input before dispatching
Example fix
// before
dispatchSubagent({ task: hugeDocument });
// after
dispatchSubagent({ task: "Summarize the file at " + path + " (read it yourself)" }); Defensive patterns
Strategy: validation
Validate before calling
if (typeof task !== "string" || task.length > subagentRuntime.maxInputChars) {
task = summarizeOrTruncate(task, subagentRuntime.maxInputChars);
} Try / catch
try {
await dispatchSubagent({ task });
} catch (e) {
if (e.message === "cave_subagent_input_limit") {
await dispatchSubagent({ task: task.slice(0, maxInputChars - 1) });
} else throw e;
} Prevention
- Truncate or summarize task input to maxInputChars before dispatch
- Pass file paths instead of embedding file contents in tasks
- Set maxInputChars generously for document-processing workflows
- Log task length on dispatch to spot near-limit inputs
When it happens
Trigger: Calling a subagent tool where typeof params.task === "string" but task.length > runtime.maxInputChars — e.g. pasting a large document as the task.
Common situations: Asking a subagent to process a big file's contents inline instead of by path; configured maxInputChars too low for the workflow; model echoing huge prior output back as the task text.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- cave_subagent_call_budget
- cave_subagent_concurrency_limit
- cave_subagent_context_budget
- cave_subagent_depth_limit
- cannot remember empty text
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/1ff3d3f80b6e4f91.
Report an issue: GitHub.
Appendix: source
Thrown at packages/agent/src/runtime.ts:3872
async function executeSubagent(
toolDefinition: ToolDefinition,
params: unknown,
signal: AbortSignal | undefined,
parentOptions: InternalRunOptions,
usage: NestedUsage,
executionContext: InternalExecutionContext,
parentMeter: BudgetMeter | undefined,
parentDeadlineAt: number | undefined,
): Promise<unknown> {
const runtime = toolDefinition.runtime;
if (runtime?.kind !== "subagent") throw new Error("cave_subagent_runtime_missing");
if (params === null || typeof params !== "object" || Array.isArray(params) ||
typeof (params as { task?: unknown }).task !== "string") {
throw new Error("cave_subagent_arguments_invalid");
}
const task = (params as { task: string }).task;
if (task.length > runtime.maxInputChars) throw new Error("cave_subagent_input_limit");
const calls = usage.calls.get(toolDefinition.name) ?? 0;
if (calls >= runtime.maxCalls) throw new Error("cave_subagent_call_budget");
// Reserve synchronously before any await so parallel Pi tool dispatch cannot
// pass the same maxCalls check twice.
usage.calls.set(toolDefinition.name, calls + 1);
const depth = executionContext.depth;
const depthLimit = Math.min(
parentOptions.maxSubagentDepth ?? DEFAULT_SUBAGENT_DEPTH_LIMIT,
ABSOLUTE_SUBAGENT_DEPTH_LIMIT,
);
if (depth + 1 > depthLimit) throw new Error("cave_subagent_depth_limit");
// The wallet is carved here, still synchronously, for the same reason: two
// subagents dispatched in one turn must not both be funded out of the same
// remaining budget.
const walletAmount = parentMeter === undefined
? undefined
: parentMeter.denomination === "usd" ? runtime.maxCostUsd : runtime.maxTokens;
if (parentMeter !== undefined && walletAmount === undefined) {View on GitHub (pinned to 3ee70a1026)