e2b-dev / e2b-dev/runtime

fix(api): GetSandboxesSandboxID omits VolumeMounts and sets empty string Alias for paused sandboxes

Open Beginner friendly
#3,575 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
1.6k
Forks
438
PR merge metrics
No merged PRs in 30d

Description

Problem

When querying sandbox metadata via GET /sandboxes/{sandboxID} (packages/api/internal/handlers/sandbox_get.go), paused or stopped sandboxes loaded from lastSnapshot exhibit two payload inconsistencies with the OpenAPI specification and list endpoints:

  1. Missing VolumeMounts in Paused Sandbox Response:
    When a sandbox is paused, lastSnapshot.Snapshot.Config.VolumeMounts contains all persistent volume mount mappings. However, GetSandboxesSandboxID constructs api.SandboxDetail without populating the VolumeMounts field, resulting in "volume_mounts": null or omission in the JSON response. In contrast, the list endpoint GET /v2/sandboxes (packages/api/internal/handlers/sandboxes_list.go:L292) correctly maps VolumeMounts for paused sandboxes via convertFromDBMountsToAPIMounts.

  2. Malformed Alias Serialized as "" (Empty String) instead of null / Omission:
    When a paused sandbox has no aliases, pausedAlias := firstAlias(lastSnapshot.Aliases) returns "" (empty string). sandbox.Alias = &pausedAlias then assigns a non-nil pointer to "". When serialized to JSON, this emits "alias": "" instead of null or omitting the property, violating the OpenAPI schema contract for optional string fields.

  3. Potential Nil Pointer Panic on a.orchestrator:
    GetSandboxesSandboxID attempts to call a.orchestrator.GetSandbox without verifying a.orchestrator != nil, causing panics in isolated unit tests and environments where the orchestrator client is nil.

Root Cause

In packages/api/internal/handlers/sandbox_get.go:L235-L265:

// Current implementation for paused sandboxes:
pausedAlias := firstAlias(lastSnapshot.Aliases)
sandbox = api.SandboxDetail{
    // VolumeMounts is omitted completely
    Alias: &pausedAlias, // Points to "" when len(Aliases) == 0
    ...
}

Comparison of metadata mapping across endpoints:

Endpoint Paused Sandbox VolumeMounts Empty Alias Representation
GET /v2/sandboxes (sandboxes_list.go) Populated via convertFromDBMountsToAPIMounts nil (omitted)
GET /sandboxes/{id} (Current) nil (omitted) &"" (serialized as "")
GET /sandboxes/{id} (Expected) Populated from Config.VolumeMounts nil (omitted)

Reproduction Steps

  1. Create a sandbox with persistent volume mounts: POST /sandboxes with volume_mounts: [{"name": "my-vol", "path": "/mnt/data"}].
  2. Pause the sandbox: POST /sandboxes/{id}/pause.
  3. Query the paused sandbox: GET /sandboxes/{id}.
  4. Observed:
    • volume_mounts is null or missing from the JSON payload.
    • alias is "" (empty string) if no alias was assigned.
  5. Expected:
    • volume_mounts contains [{"name": "my-vol", "path": "/mnt/data"}].
    • alias is null or omitted when no alias exists.

Technical Context

  • File affected: packages/api/internal/handlers/sandbox_get.go
  • Subsystem: Control Plane API / Sandboxes
  • Impact: Medium (API Schema compliance, client SDK consistency, and paused sandbox metadata fidelity)

Proposed Changes

# Change File(s) Affected Complexity
1 Add nil check on a.orchestrator != nil before calling GetSandbox sandbox_get.go Trivial
2 Extract volumeMounts from lastSnapshot.Snapshot.Config.VolumeMounts and pass to api.SandboxDetail sandbox_get.go Low
3 Populate sandbox.Alias only when len(lastSnapshot.Aliases) > 0, leaving it nil otherwise sandbox_get.go Trivial
4 Add unit test asserting VolumeMounts and nil alias on paused snapshot sandbox_get_test.go Low

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/api/internal/handlers/sandbox_get.go, especially the paused-sandbox mapping around lines 235-265, and compare its VolumeMounts and Alias handling with sandboxes_list.go. Add the orchestrator nil guard and cover the paused snapshot case in sandbox_get_test.go. Done means paused responses preserve volume mounts, omit an empty alias, and do not panic with a nil orchestrator.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.