Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/js-sdk/src/sandbox/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ export class Sandbox extends SandboxApi {
*
* @param opts connection options.
*
* @returns sandbox ID that can be used to resume the sandbox.
* @returns true if the sandbox was paused successfully, false if it was already paused.
*
* @example
* ```ts
Expand All @@ -585,14 +585,14 @@ export class Sandbox extends SandboxApi {
* ```
*/
async pause(opts?: ConnectionOpts): Promise<boolean> {
return await SandboxApi.pause(this.sandboxId, opts)
return await SandboxApi.pause(this.sandboxId, { ...this.connectionConfig, ...opts })
}

/**
* @deprecated Use {@link Sandbox.pause} instead.
*/
async betaPause(opts?: ConnectionOpts): Promise<boolean> {
return await SandboxApi.betaPause(this.sandboxId, opts)
return await SandboxApi.betaPause(this.sandboxId, { ...this.connectionConfig, ...opts })
}

/**
Expand Down
75 changes: 75 additions & 0 deletions packages/js-sdk/tests/sandbox/pause.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { assert, expect } from 'vitest'

import { Sandbox } from '../../src'
import { isDebug, sandboxTest, template } from '../setup'
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

template is imported but not used anywhere in this new test file. Removing it will keep the test file cleaner and avoid lint failures in stricter configurations.

Suggested change
import { isDebug, sandboxTest, template } from '../setup'
import { isDebug, sandboxTest } from '../setup'

Copilot uses AI. Check for mistakes.

/**
* Regression test: Sandbox.connect() with explicit apiKey should allow
* pause() to succeed even when E2B_API_KEY is not set in the environment.
*
* See: https://github.com/e2b-dev/E2B/pull/1218
*/
sandboxTest.skipIf(isDebug)(
'pause() uses apiKey from connectionConfig when E2B_API_KEY is not set',
async ({ sandbox }) => {
// Save and clear the environment API key
const savedApiKey = process.env.E2B_API_KEY
delete process.env.E2B_API_KEY

try {
// Get the apiKey that was used to create this sandbox
const apiKey = process.env.E2B_API_KEY || savedApiKey
expect(apiKey).toBeDefined()

// Connect to the sandbox with an explicit apiKey (E2B_API_KEY is now unset)
const connected = Sandbox.connect(sandbox.sandboxId, { apiKey })
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expect(apiKey).toBeDefined() is a runtime check but does not help TypeScript narrow apiKey to string at compile time. To avoid accidentally passing undefined into Sandbox.connect (and to satisfy TS if apiKey is typed as required), assign with an explicit guard (throw/assert) and/or pass apiKey! after the assertion.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Await Sandbox.connect before calling instance methods

Sandbox.connect(...) is async and returns a Promise<Sandbox>, but this test stores it without await and then calls connected.pause()/connected.isRunning(). In Node this means connected is a Promise, so method calls fail with TypeError before the pause behavior is exercised; the same pattern appears again later in this file (line 63).

Useful? React with 👍 / 👎.


// pause() should succeed using the apiKey from connectionConfig
// rather than requiring E2B_API_KEY to be set
const paused = await connected.pause()
assert.isTrue(paused, 'pause() should return true when successfully pausing a running sandbox')

// Verify the sandbox is actually paused
assert.isFalse(await connected.isRunning(), 'sandbox should be paused after pause()')
} finally {
// Restore the environment API key
if (savedApiKey) {
process.env.E2B_API_KEY = savedApiKey
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Environment restoration is currently conditional on savedApiKey being truthy; if it was set to an empty string, the test will not restore the original value and could leak mutated process state into subsequent tests. Prefer checking savedApiKey !== undefined (restore), and otherwise explicitly delete process.env.E2B_API_KEY.

Suggested change
if (savedApiKey) {
process.env.E2B_API_KEY = savedApiKey
if (savedApiKey !== undefined) {
process.env.E2B_API_KEY = savedApiKey
} else {
delete process.env.E2B_API_KEY

Copilot uses AI. Check for mistakes.
}
}
}
)

sandboxTest.skipIf(isDebug)(
'pause() returns false when sandbox is already paused',
async ({ sandbox }) => {
// Pause the sandbox first
const firstPause = await sandbox.pause()
assert.isTrue(firstPause, 'first pause() should return true')

// Try to pause again - should return false since already paused
const secondPause = await sandbox.pause()
assert.isFalse(secondPause, 'pause() should return false when sandbox is already paused')
}
)

sandboxTest.skipIf(isDebug)(
'pause() works on connected sandbox with apiKey in connectionConfig',
async ({ sandbox }) => {
const apiKey = process.env.E2B_API_KEY
expect(apiKey).toBeDefined()

// Connect to the sandbox using apiKey from connectionConfig
const connected = Sandbox.connect(sandbox.sandboxId, { apiKey })

// Ensure the sandbox is running before pausing
assert.isTrue(await sandbox.isRunning())

// Pause the connected sandbox
const paused = await connected.pause()
assert.isTrue(paused, 'pause() should succeed on connected sandbox')

// Verify it's paused
assert.isFalse(await connected.isRunning())
}
)
Loading