mastra-ai/mastra · error

Invalid worker environment variable name: ${key}

Error message

Invalid worker environment variable name: ${key}

What it means

Worker environment variables are passed as a plain object and must use valid POSIX identifier names: starting with a letter or underscore and containing only [A-Za-z0-9_]. Keys that fail the regex are rejected with the offending key in the message.

Source

Thrown at deployers/sandbox/src/worker.ts:172

    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.`,
    );
  }
  validateExecutionId(options.executionId);
  if (!options.command || /[\0\r\n]/.test(options.command)) {
    throw new Error('Worker command must be a non-empty executable path.');
  }
  if (options.args?.some(arg => arg.includes('\0'))) throw new Error('Worker arguments must not contain NUL bytes.');
  for (const key of Object.keys(options.env ?? {})) {
    if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) throw new Error(`Invalid worker environment variable name: ${key}`);
  }
  validateRelativePath(options.workingDirectory ?? '.', 'workingDirectory');
  validateInput(options.input);
  for (const [name, value] of [
    ['inputLimitBytes', options.inputLimitBytes],
    ['startupTimeoutMs', options.startupTimeoutMs],
    ['executionTimeoutMs', options.executionTimeoutMs],
    ['terminationGraceMs', options.terminationGraceMs],
  ] as const) {
    if (value !== undefined && (!Number.isFinite(value) || value <= 0))
      throw new Error(`${name} must be greater than zero.`);
  }
  const resourceLimits = options.resourceLimits;
  if (resourceLimits) {
    const knownLimits = new Set(['cpuTimeSeconds', 'addressSpaceBytes', 'fileSizeBytes', 'openFiles']);
    for (const name of Object.keys(resourceLimits)) {
      if (!knownLimits.has(name)) throw new Error(`Unknown worker resource limit: ${name}.`);
    }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Rename the variable to a valid POSIX identifier (letters, digits, underscores; no leading digit).
  2. Filter or map invalid keys out of the env object before calling deployWorkerToSandbox.
  3. Sanitize when importing from external config: normalize keys (replace - and . with _) and drop empties.

Example fix

// before
await deployWorkerToSandbox({ sandbox, command: 'node', env: { 'MY-KEY': 'v' } });
// after
await deployWorkerToSandbox({ sandbox, command: 'node', env: { MY_KEY: 'v' } });
Defensive patterns

Strategy: validation

Validate before calling

for (const key of Object.keys(env ?? {})) {
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) throw new Error(`Invalid worker env var name: ${key}`);
}

Type guard

const isValidEnvKey = (k: string): boolean => /^[A-Za-z_][A-Za-z0-9_]*$/.test(k);

Prevention

When it happens

Trigger: Passing options.env with keys like 'MY-VAR', '2FA_TOKEN', 'my var', or empty-string keys to deployWorkerToSandbox.

Common situations: Copy-pasting .env lines with dashes; letting secrets-manager key names flow through unchanged; accidentally including comments ('# NOTE') or empty lines as keys when parsing env files manually.

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/c533f2340ec9adaa. Report an issue: GitHub.