{"record":{"id":"072ed9e10e3ec079","repo":"JuliusBrussee/caveman","slug":"cave-subagent-concurrency-limit-invalid","errorCode":"cave_subagent_concurrency_limit_invalid","errorMessage":"cave_subagent_concurrency_limit_invalid","messagePattern":"cave_subagent_concurrency_limit_invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/runtime.ts","lineNumber":1067,"sourceCode":"    },\n  } as AsyncGenerator<CavemanRunEvent>;\n}\n\nasync function* streamAgentInternal(\n  definition: AgentDefinition,\n  input: string,\n  options: InternalRunOptions,\n  executionContext: InternalExecutionContext,\n): AsyncGenerator<CavemanRunEvent> {\n  if (options.maxSubagentInvocations !== undefined &&\n      (!Number.isSafeInteger(options.maxSubagentInvocations) || options.maxSubagentInvocations <= 0 ||\n        options.maxSubagentInvocations > ABSOLUTE_SUBAGENT_INVOCATION_LIMIT)) {\n    throw new Error(\"cave_subagent_invocation_limit_invalid\");\n  }\n  if (options.maxConcurrentSubagents !== undefined &&\n      (!Number.isSafeInteger(options.maxConcurrentSubagents) || options.maxConcurrentSubagents <= 0 ||\n        options.maxConcurrentSubagents > ABSOLUTE_SUBAGENT_INVOCATION_LIMIT)) {\n    throw new Error(\"cave_subagent_concurrency_limit_invalid\");\n  }\n  if (options.lockedBuild !== undefined && options.candidatePlan !== undefined) {\n    throw new Error(\"cave_execution_authorization_ambiguous\");\n  }\n  // Budget shape is settled before anything else happens: an ambiguous or\n  // unbounded budget must fail at run() start, not after the first dollar.\n  // maxCostUsd and budget are two different contracts for the same money —\n  // one terminates with an error, the other returns a planned partial result —\n  // so carrying both would leave the run's own stop semantics undecided.\n  if (options.budget !== undefined && options.maxCostUsd !== undefined) {\n    throw new Error(\"cave_budget_conflicting_cap\");\n  }\n  const budgetMeter = executionContext.budgetMeter ?? (options.budget === undefined\n    ? undefined\n    : new BudgetMeter(normalizeRunBudget(options.budget)));\n  if (options.deadlineMs !== undefined &&\n      (!Number.isSafeInteger(options.deadlineMs) || options.deadlineMs <= 0)) {\n    throw new Error(\"cave_run_deadline_invalid\");","sourceCodeStart":1049,"sourceCodeEnd":1085,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/runtime.ts#L1049-L1085","documentation":"Thrown at the start of streamAgentInternal when RunOptions.maxConcurrentSubagents is present but invalid: it must be a safe integer, strictly positive, and at most ABSOLUTE_SUBAGENT_INVOCATION_LIMIT (1,000,000). This option bounds simultaneously active descendants on the root ledger; capacity is released after success, error, or abort, so a malformed cap is rejected up front rather than silently ignored.","triggerScenarios":"Setting maxConcurrentSubagents to 0, a negative number, a non-integer like 2.5, NaN, or a value above 1,000,000.","commonSituations":"Computing concurrency from CPU count or config and passing 0 on small machines; passing a parsed env value that is empty (NaN); mixing up 'no concurrency limit' (should be omitted) with 0.","solutions":["Pass a positive safe integer, e.g. maxConcurrentSubagents: 4, or omit it for no concurrency bound","For 'serial' subagent execution use 1, not 0","Sanitize computed values: Math.max(1, Math.floor(n))"],"exampleFix":"// before\nawait agent.run(input, { maxConcurrentSubagents: cpus - 4 }); // 0 on a 4-core box\n\n// after\nawait agent.run(input, {\n  maxConcurrentSubagents: Math.max(1, cpus - 4),\n});","handlingStrategy":"validation","validationCode":"const concurrency = Math.max(1, Math.floor(config.concurrency ?? 1));\nawait agent.run(input, { maxConcurrentSubagents: concurrency });","typeGuard":"const isValidConcurrency = (v: unknown): v is number =>\n  typeof v === \"number\" && Number.isSafeInteger(v) && v > 0 && v <= 1_000_000;","tryCatchPattern":null,"preventionTips":["Use 1 for serial subagent execution, omit for unbounded","Guard computed concurrency (cpu counts, config) against 0","Never pass fractional concurrency values"],"tags":["subagents","concurrency","validation"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}