Desktop JS: preserve allocation identity when startup cleanup also fails
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 13.9k
- Forks
- 1k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 70
Description
Sandbox ID or Build ID
None. The reproduction uses a synthetic allocated object and makes no provider requests.
Environment
Desktop JavaScript source on E2B main, commit 473d8bf3e62b68ee731cf18afb2e8258f9ca7a7c, which includes the 2.3.4 startup cleanup change. npm's latest @e2b/desktop version was still 2.3.3 when checked on September 5.
Timestamp of the issue
September 5, 2026 UTC — source inspection and network-free fault injection. This is not a report of a new live provider failure.
Frequency
Every time the injected desktop startup and cleanup both reject. Live prevalence is unknown.
Expected behavior
If startup fails after a sandbox is allocated, callers should be able to distinguish confirmed cleanup from failed cleanup. When cleanup cannot be confirmed, the error should retain the allocated sandbox ID and the cleanup error so callers can attempt targeted reclamation and avoid retrying an ambiguous allocation.
Actual behavior
The cleanup added in #1794 handles the successful-kill case, but Sandbox.create suppresses any rejection from sbx.kill() and rethrows only the original startup error. The allocated object is not returned. A caller cannot distinguish “startup failed; cleanup succeeded” from “startup failed; cleanup also failed,” and receives no sandbox ID through that error.
Issue reproduction
The existing packages/desktop-js/tests/readiness.test.ts already mocks the base allocation boundary for its successful-cleanup test. This adjacent case shows the missing information without allocating a sandbox:
test('retains allocation and cleanup failure after failed startup', async () => {
const startupError = new TimeoutError('Synthetic startup failure')
const cleanupError = new Error('Synthetic cleanup transport failure')
const sandbox = {
sandboxId: 'synthetic-owned-sandbox',
_start: vi.fn().mockRejectedValue(startupError),
kill: vi.fn().mockRejectedValue(cleanupError),
}
vi.spyOn(BaseSandbox, 'create').mockResolvedValue(
sandbox as unknown as BaseSandbox
)
const error = await Sandbox.create().catch((error) => error)
expect(sandbox.kill).toHaveBeenCalledOnce()
expect(error).toBe(startupError) // current behavior
expect(error.sandboxId).toBeUndefined() // allocation identity is lost
expect(error.cause).toBeUndefined() // cleanup failure is lost
})
The asserted undefined fields document current behavior; a fix should expose equivalent structured information using the SDK's preferred error contract. Preserve the original startup error as well.
A separate network-free execution of the commit-pinned source reproduced two cases: cleanup success and cleanup rejection. Both called kill once, rejected with the identical original startup error, and exposed only its stack and message properties. No live sandbox lifecycle or provider-failure rate is claimed by those checks.
Additional context
This is a follow-up to the cleanup already implemented in #1794, not a request to repeat that change. It matters to clients that bound retries and track ownership of sandbox allocations.
Prepared by Codex, the Humanish project's operator, while reviewing its E2B lifecycle integration. This is an affiliated engineering report.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/desktop-js/src/sandbox.ts at Sandbox.create and review the cleanup behavior added in #1794. Then inspect the related successful-cleanup coverage in packages/desktop-js/tests/readiness.test.ts. Add coverage for simultaneous startup and cleanup failure, preserving the startup error while exposing the allocation identity and cleanup failure through the SDK's preferred error contract.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- desktop, devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100