{"record":{"id":"1983437820aecf89","repo":"mastra-ai/mastra","slug":"terminationgracems-must-be-greater-than-zero","errorCode":null,"errorMessage":"terminationGraceMs must be greater than zero.","messagePattern":"terminationGraceMs must be greater than zero\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"deployers/sandbox/src/worker.ts","lineNumber":147,"sourceCode":"    throw workerPhaseError('install', error);\n  }\n\n  return createExecution(config, executionId, options.input);\n}\n\n/** Reattach to a persisted worker execution without its original launch configuration. */\nexport async function attachWorkerDeployment(options: AttachWorkerDeploymentOptions): Promise<SandboxWorkerExecution> {\n  if (!options.sandbox.executeCommand) {\n    throw new Error(\n      `Sandbox provider \"${options.sandbox.provider}\" does not support executeCommand, which is required for worker deploys.`,\n    );\n  }\n  validateExecutionId(options.executionId);\n  if (\n    options.terminationGraceMs !== undefined &&\n    (!Number.isFinite(options.terminationGraceMs) || options.terminationGraceMs <= 0)\n  ) {\n    throw new Error('terminationGraceMs must be greater than zero.');\n  }\n\n  let remoteDir: string | undefined;\n  const config: WorkerExecutionConfig = {\n    sandbox: options.sandbox,\n    resolveRemoteDir: async () => (remoteDir ??= await resolveRemoteDir(options.sandbox, options.remoteDir)),\n    terminationGraceMs: options.terminationGraceMs ?? 5_000,\n  };\n  const info = await getInfoSafe(options.sandbox);\n  return execution(config, options.executionId, info?.id ?? options.sandbox.id, info?.timeoutAt);\n}\n\nfunction validateOptions(options: DeployWorkerToSandboxOptions): void {\n  if (!options.sandbox.executeCommand) {\n    throw new Error(\n      `Sandbox provider \"${options.sandbox.provider}\" does not support executeCommand, which is required for worker deploys.`,\n    );\n  }","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/deployers/sandbox/src/worker.ts#L129-L165","documentation":"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.","triggerScenarios":"Passing terminationGraceMs of 0, a negative number, NaN, or Infinity to attachWorkerDeployment.","commonSituations":"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).","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."],"exampleFix":"// before\nawait attachWorkerDeployment({ sandbox, executionId, terminationGraceMs: 0 });\n// after\nawait attachWorkerDeployment({ sandbox, executionId, terminationGraceMs: 5000 });","handlingStrategy":"validation","validationCode":"if (opts.terminationGraceMs !== undefined && (!Number.isFinite(opts.terminationGraceMs) || opts.terminationGraceMs <= 0)) throw new Error('terminationGraceMs must be a positive finite number');","typeGuard":"const isValidGraceMs = (v: unknown): v is number =>\n  typeof v === 'number' && Number.isFinite(v) && v > 0;","tryCatchPattern":null,"preventionTips":["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"],"tags":["worker","validation","configuration"],"backgroundTag":"invalid-option-value","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}