mastra-ai/mastra · error
terminationGraceMs must be greater than zero.
Error message
terminationGraceMs must be greater than zero.
What it means
attachWorkerDeployment validates terminationGraceMs when provided: it must be a finite number greater than zero, since it is used as the SIGTERM-to-SIGKILL grace period when stopping the worker. Invalid values are rejected before any sandbox work starts.
Source
Thrown at deployers/sandbox/src/worker.ts:147
throw workerPhaseError('install', error);
}
return createExecution(config, executionId, options.input);
}
/** Reattach to a persisted worker execution without its original launch configuration. */
export async function attachWorkerDeployment(options: AttachWorkerDeploymentOptions): Promise<SandboxWorkerExecution> {
if (!options.sandbox.executeCommand) {
throw new Error(
`Sandbox provider "${options.sandbox.provider}" does not support executeCommand, which is required for worker deploys.`,
);
}
validateExecutionId(options.executionId);
if (
options.terminationGraceMs !== undefined &&
(!Number.isFinite(options.terminationGraceMs) || options.terminationGraceMs <= 0)
) {
throw new Error('terminationGraceMs must be greater than zero.');
}
let remoteDir: string | undefined;
const config: WorkerExecutionConfig = {
sandbox: options.sandbox,
resolveRemoteDir: async () => (remoteDir ??= await resolveRemoteDir(options.sandbox, options.remoteDir)),
terminationGraceMs: options.terminationGraceMs ?? 5_000,
};
const info = await getInfoSafe(options.sandbox);
return execution(config, options.executionId, info?.id ?? options.sandbox.id, info?.timeoutAt);
}
function validateOptions(options: DeployWorkerToSandboxOptions): void {
if (!options.sandbox.executeCommand) {
throw new Error(
`Sandbox provider "${options.sandbox.provider}" does not support executeCommand, which is required for worker deploys.`,
);
}View on GitHub (pinned to 75dd419e61)
Solutions
- Pass a positive finite number of milliseconds (e.g. 5000 for 5s).
- If the option is unset upstream, omit it entirely (undefined is allowed) rather than passing 0.
- Check the parsing path — wrap Number() conversions and validate with Number.isFinite.
Example fix
// before
await attachWorkerDeployment({ sandbox, executionId, terminationGraceMs: 0 });
// after
await attachWorkerDeployment({ sandbox, executionId, terminationGraceMs: 5000 }); Defensive patterns
Strategy: validation
Validate before calling
if (opts.terminationGraceMs !== undefined && (!Number.isFinite(opts.terminationGraceMs) || opts.terminationGraceMs <= 0)) throw new Error('terminationGraceMs must be a positive finite number'); Type guard
const isValidGraceMs = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && v > 0;
Prevention
- Omit the option instead of passing 0 to disable it
- Parse durations with Number() and validate with Number.isFinite
- Standardize on milliseconds in your config schema
When it happens
Trigger: Passing terminationGraceMs of 0, a negative number, NaN, or Infinity to attachWorkerDeployment.
Common situations: Copy-pasted config with grace period left at 0; parsing env vars/JSON strings without numeric coercion producing NaN; unit confusion (seconds entered where milliseconds expected resulting in tiny/zero values after conversion).
Understand the failure class
Background: Invalid option value errors: "must be one of", "is not a valid", and "only allows" failures explained — this error's family across 23 libraries.
Related errors
- Worker command must be a non-empty executable path.
- ${name} must be greater than zero.
- Unknown worker resource limit: ${name}.
- @mastra/livekit: set exactly one reply generator — `generate
- @mastra/livekit: set `agent` or `workflow`, not both — they
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/1983437820aecf89.
Report an issue: GitHub.