github/copilot-sdk · error
Factory limit "timeoutSeconds" must be a positive, finite…
Error message
Factory limit "timeoutSeconds" must be a positive, finite number of seconds
What it means
This error is thrown by validateLimits when a factory definition specifies a timeoutSeconds limit that is not a finite positive number. The library validates factory limits at defineFactory time so invalid configuration fails fast instead of producing undefined behavior at runtime. timeoutSeconds controls how long factory operations may run, so zero, negative, NaN, or Infinity values are meaningless and rejected.
Solutions
- Pass a positive finite number of seconds for limits.timeoutSeconds, e.g. 30.
- If the value comes from config or env, validate/coerce it before calling defineFactory (Number.isFinite check).
- Fix unit conversions so the result is in seconds, not milliseconds or a NaN-producing operation.
- Remove the timeoutSeconds field entirely if you do not intend to set a timeout.
Example fix
// before
defineFactory({ name: 'build', limits: { timeoutSeconds: Number(process.env.TIMEOUT) } });
// after
const t = Number(process.env.TIMEOUT);
defineFactory({ name: 'build', limits: { timeoutSeconds: Number.isFinite(t) && t > 0 ? t : 30 } }); Defensive patterns
Strategy: validation
Validate before calling
function isValidTimeout(t) { return typeof t === 'number' && Number.isFinite(t) && t > 0 && t <= 2147483.647; }
if (!isValidTimeout(opts.limits?.timeoutSeconds)) throw new TypeError('timeoutSeconds must be a positive finite number of seconds'); Type guard
function hasValidTimeout(l) { return l.timeoutSeconds === undefined || (Number.isFinite(l.timeoutSeconds) && l.timeoutSeconds > 0); } Try / catch
try {
defineFactory({ ...meta, limits: { timeoutSeconds: t } });
} catch (e) {
if (String(e.message).includes('"timeoutSeconds"')) {
console.error('Bad timeoutSeconds config:', t);
}
throw e;
} Prevention
- Coerce env/config values through Number() and Number.isFinite before use
- Keep all timeouts in one unit (seconds) with named constants
- Add a schema (zod) validation on factory limits before defineFactory
- Never pass raw env strings as numeric limits
When it happens
Trigger: Calling defineFactory with limits.timeoutSeconds set to 0, a negative number, NaN, or Infinity. Also occurs when timeoutSeconds is computed dynamically (e.g. from config or env) and the computation yields NaN or a non-positive value.
Common situations: Reading timeout values from environment variables or JSON config where the value is a string or missing and becomes NaN after numeric coercion; a config template with a placeholder 0; mixing units (milliseconds vs seconds) and dividing wrongly.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Factory limit "timeoutSeconds" must not exceed
- Factory limit "maxAiCredits" must be a positive, finite…
- sessionFs.initialCwd is required
- sessionFs.sessionStatePath is required
- sessionFs.conventions must be either 'windows' or 'posix'
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/63952f778c6541bc.
Report an issue: GitHub.
Appendix: source
Thrown at nodejs/src/factory.ts:436
function validateLimits(meta: FactoryMeta): void {
const limits = meta.limits;
if (!limits) {
return;
}
for (const field of ["maxConcurrentSubagents", "maxTotalSubagents"] as const) {
const value = limits[field];
if (value !== undefined && (!Number.isInteger(value) || value <= 0)) {
throw new Error(`Factory limit "${field}" must be a positive integer`);
}
}
if (
limits.timeoutSeconds !== undefined &&
(!Number.isFinite(limits.timeoutSeconds) || limits.timeoutSeconds <= 0)
) {
throw new Error(
'Factory limit "timeoutSeconds" must be a positive, finite number of seconds'
);
}
if (
limits.timeoutSeconds !== undefined &&
limits.timeoutSeconds > MAX_FACTORY_TIMEOUT_SECONDS
) {
throw new Error(
`Factory limit "timeoutSeconds" must not exceed ${MAX_FACTORY_TIMEOUT_SECONDS} seconds`
);
}
if (limits.maxAiCredits !== undefined) {
const maxNanoAiu = Math.round(limits.maxAiCredits * NANO_AIU_PER_AIU);
if (
!Number.isFinite(limits.maxAiCredits) ||
limits.maxAiCredits <= 0 ||
!Number.isSafeInteger(maxNanoAiu) ||View on GitHub (pinned to cd8cf15dc3)