diff --git a/src/content/docs/sandbox/api/commands.mdx b/src/content/docs/sandbox/api/commands.mdx index c8aacaea1d39c00..d2486d1644876a6 100644 --- a/src/content/docs/sandbox/api/commands.mdx +++ b/src/content/docs/sandbox/api/commands.mdx @@ -25,6 +25,8 @@ const result = await sandbox.exec(command: string, options?: ExecOptions): Promi - `stream` - Enable streaming callbacks (default: `false`) - `onOutput` - Callback for real-time output: `(stream: 'stdout' | 'stderr', data: string) => void` - `timeout` - Maximum execution time in milliseconds + - `env` - Environment variables for this command: `Record` + - `cwd` - Working directory for this command **Returns**: `Promise` with `success`, `stdout`, `stderr`, `exitCode` @@ -43,6 +45,15 @@ await sandbox.exec('npm install', { stream: true, onOutput: (stream, data) => console.log(`[${stream}] ${data}`) }); + +// With environment variables (undefined values are skipped) +await sandbox.exec('node app.js', { + env: { + NODE_ENV: 'production', + PORT: '3000', + DEBUG_MODE: undefined // Skipped, uses container default or unset + } +}); ``` @@ -94,7 +105,11 @@ const process = await sandbox.startProcess(command: string, options?: ProcessOpt - `command` - The command to start as a background process - `options` (optional): - `cwd` - Working directory - - `env` - Environment variables + - `env` - Environment variables: `Record` + - `timeout` - Maximum execution time in milliseconds + - `processId` - Custom process ID + - `encoding` - Output encoding (default: `'utf8'`) + - `autoCleanup` - Whether to clean up process on sandbox sleep **Returns**: `Promise` object with: - `id` - Unique process identifier diff --git a/src/content/docs/sandbox/api/sessions.mdx b/src/content/docs/sandbox/api/sessions.mdx index e18322b43210ee0..6535560a927752b 100644 --- a/src/content/docs/sandbox/api/sessions.mdx +++ b/src/content/docs/sandbox/api/sessions.mdx @@ -26,7 +26,7 @@ const session = await sandbox.createSession(options?: SessionOptions): Promise` - `cwd` - Working directory (default: `"/workspace"`) **Returns**: `Promise` with all sandbox methods bound to this session @@ -42,7 +42,11 @@ const prodSession = await sandbox.createSession({ const testSession = await sandbox.createSession({ id: 'test', - env: { NODE_ENV: 'test', API_URL: 'http://localhost:3000' }, + env: { + NODE_ENV: 'test', + API_URL: 'http://localhost:3000', + DEBUG_MODE: undefined // Skipped, not set in this session + }, cwd: '/workspace/test' }); @@ -123,11 +127,13 @@ Deleting a session immediately terminates all running commands. The default sess Set environment variables in the sandbox. ```ts -await sandbox.setEnvVars(envVars: Record): Promise +await sandbox.setEnvVars(envVars: Record): Promise ``` **Parameters**: -- `envVars` - Key-value pairs of environment variables to set +- `envVars` - Key-value pairs of environment variables to set or unset + - `string` values: Set the environment variable + - `undefined` or `null` values: Unset the environment variable :::caution Call `setEnvVars()` **before** any other sandbox operations to ensure environment variables are available from the start. @@ -141,7 +147,8 @@ const sandbox = getSandbox(env.Sandbox, 'user-123'); await sandbox.setEnvVars({ API_KEY: env.OPENAI_API_KEY, DATABASE_URL: env.DATABASE_URL, - NODE_ENV: 'production' + NODE_ENV: 'production', + OLD_TOKEN: undefined // Unsets OLD_TOKEN if previously set }); // Now commands can access these variables diff --git a/src/content/docs/sandbox/configuration/environment-variables.mdx b/src/content/docs/sandbox/configuration/environment-variables.mdx index a92441e21390c41..658e6655a46fb11 100644 --- a/src/content/docs/sandbox/configuration/environment-variables.mdx +++ b/src/content/docs/sandbox/configuration/environment-variables.mdx @@ -30,6 +30,16 @@ await sandbox.exec("python seed.py"); // Has DATABASE_URL and API_KEY **Use when:** You need the same environment variables for multiple commands. +**Unsetting variables**: Pass `undefined` or `null` to unset environment variables: + +```typescript +await sandbox.setEnvVars({ + API_KEY: 'new-key', // Sets API_KEY + OLD_SECRET: undefined, // Unsets OLD_SECRET + DEBUG_MODE: null // Unsets DEBUG_MODE +}); +``` + ### 2. Per-command with exec() options Pass environment variables for a specific command: @@ -71,6 +81,56 @@ await session.exec("python seed.py"); **Use when:** You need isolated execution contexts with different environment variables running concurrently. +## Unsetting environment variables + +The Sandbox SDK supports unsetting environment variables by passing `undefined` or `null` values. This enables idiomatic JavaScript patterns for managing configuration: + +```typescript +await sandbox.setEnvVars({ + // Set new values + API_KEY: 'new-key', + DATABASE_URL: env.DATABASE_URL, + + // Unset variables (removes them from the environment) + OLD_API_KEY: undefined, + TEMP_TOKEN: null +}); +``` + +**Before this change**: Passing `undefined` values would throw a runtime error. + +**After this change**: `undefined` and `null` values run `unset VARIABLE_NAME` in the shell. + +### Use cases for unsetting + +**Remove sensitive data after use:** + +```typescript +// Use a temporary token +await sandbox.setEnvVars({ TEMP_TOKEN: 'abc123' }); +await sandbox.exec('curl -H "Authorization: $TEMP_TOKEN" api.example.com'); + +// Clean up the token +await sandbox.setEnvVars({ TEMP_TOKEN: undefined }); +``` + +**Conditional environment setup:** + +```typescript +await sandbox.setEnvVars({ + API_KEY: env.API_KEY, + DEBUG_MODE: env.NODE_ENV === 'development' ? 'true' : undefined, + PROFILING: env.ENABLE_PROFILING ? 'true' : undefined +}); +``` + +**Reset to system defaults:** + +```typescript +// Unset to fall back to container's default NODE_ENV +await sandbox.setEnvVars({ NODE_ENV: undefined }); +``` + ## Common patterns ### Pass Worker secrets to sandbox