Skip to content

SpawnOptions.env: support unsetting inherited environment variables per run #405

@kamilio

Description

@kamilio

Summary

The released public SpawnOptions.env applies string overrides by merging them over process.env, but it cannot remove an inherited environment variable for one spawned run.

This leaves consumers unable to safely strip inherited credentials or other sensitive variables from a specific agent invocation without mutating the parent process environment or replacing the value with an empty string.

Reproduction / current behavior

The public type is currently:

env?: Record<string, string>;

The spawn path constructs the child environment approximately as:

const processEnv = { ...process.env, ...options.env };

So a consumer cannot express “do not inherit ASANA_ACCESS_TOKEN for this run.” Omitting the key inherits it; setting undefined is rejected by the public type; setting "" is not equivalent to removing the variable and can affect presence-based checks.

Consumer use case

quora/bug-analyzer runs dry-run agents that must not receive destructive credentials, while selected MCP servers still need those credentials to implement safe dry-run recording. After adopting per-run env overrides, normal/resumed spawns no longer need global process.env mutation, but true credential removal cannot be represented through the public API.

Requested capability

Support documented per-run unsetting semantics, for example:

await spawn("codex", {
  prompt,
  env: {
    ASANA_ACCESS_TOKEN: undefined,
  },
});

An explicit separate option such as unsetEnv: string[] would also solve it.

Acceptance criteria

  • A public SDK consumer can remove selected inherited variables for one spawn.
  • The parent process environment is never mutated.
  • CLI and ACP spawn paths behave consistently.
  • Runtime backends preserve the same unset semantics.
  • MCP server inheritance and explicit server env precedence are documented.
  • Tests cover presence-based checks, parallel conflicting runs, and inherited credential removal.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions