Skip to content

bug(server): after a compute-driver change the gateway deletes stopped sandboxes created by the previous driver #4769

Open

Description

@vineethsai7

User Story

I use OpenShell (0.1.3 and stock 0.1.5) on macOS with both the MicroVM and the Docker drivers available, one at a time, under a host-side policy agent (DefenseClaw, Apache-2.0).

I switched a gateway from compute_driver = "vm" to "docker" while a stopped, kept VM sandbox still held unpulled work. On v0.1.5 the gateway removed that sandbox from its store about 66 seconds after the switch. When I switched back to "vm", the VM driver still had the sandbox's disk, but OpenShell no longer listed it and could not start it, so the work was lost.

This affects anyone who changes the compute driver of a gateway that has kept sandboxes.

Problem Statement

The store reconcile loop compares every store record with the active driver's ListSandboxes. A record that the active driver does not list is treated as a vanished resource, even when that record was created by a different driver. The record carries the internal.openshell.ai/compute-driver annotation, which names its driver.

On the first sweep after the change, a Stopped, Stopping or Starting record is moved to Error with reason ComputeResourceMissing, and the gateway logs "Retained sandbox resource disappeared from the compute driver". On the next sweep the Error record is removed from the store, and a cleanup DeleteSandbox is sent to the new driver.

The grace period is measured from the record's creation time, not from when it went missing. Any sandbox older than five minutes is therefore removed within about two reconcile intervals.

Impact / Why This Matters

  • A stopped, kept sandbox, and any work in it that was not pulled out, is lost after a driver change, even though the old driver's resources still exist.
  • There is no warning at the switch and no way to keep the record.
  • The workaround is to pull every sandbox's work out and delete the sandboxes before changing the driver. That is easy to miss, and it is not documented.

Acceptance Criteria

  • After a change from driver A to driver B, records created by A are not moved to a terminal phase or deleted, and no cleanup for them is sent to B.
  • Such records are listed with a clear non-ready reason that names the driver that created them, for example "created on vm; the gateway runs docker".
  • Start, stop and exec on such a record fail with a clear precondition error. sandbox delete still removes the record.
  • After switching back to driver A, the sandbox can be started and its files are intact.
  • Records without a driver annotation keep today's behavior.

Reproduction Steps

  1. Start a gateway with compute_driver = "vm".
  2. Run openshell sandbox create --name keep --keep -- sh -c 'echo work > /sandbox/work.txt; sleep 600' from another terminal, then openshell sandbox stop keep while it is Ready. Wait until the sandbox is more than five minutes old. On v0.1.5 the original echo-only command entered Completed, so the sleep keeps it running until the stop.
  3. Stop the gateway, set compute_driver = "docker", and start it again.
  4. Watch the gateway log and openshell sandbox list:
    • within about one minute the log shows Retained sandbox resource disappeared from the compute driver, and keep is in Error;
    • about one minute later the log shows Removing sandbox from store, and keep is gone.
  5. Set compute_driver = "vm" and restart the gateway. openshell sandbox list does not show keep, and openshell sandbox start keep reports that it is not found. The VM driver's state directory still holds the sandbox's disk.

The same should reproduce on Linux by switching between docker and podman. I have not run that variant.

Expected: keep survives the switch in a non-destructive state and starts again after switching back.
Actual on v0.1.5: keep moved to Error on the first sweep and was deleted from the store 66 s after the switch (at record age 407 s).

Suggested UX (if applicable)

$ openshell sandbox list
NAME   PHASE        REASON
keep   Unavailable  created on compute driver "vm"; this gateway runs "docker"
$ openshell sandbox start keep
error: sandbox "keep" was created on compute driver "vm"; switch the gateway back to "vm" to start it

Environment

  • Stock OpenShell 0.1.5 release binaries, checksum verified.
  • macOS 15.8 (Darwin kernel 24.6.0), Apple silicon, Apple Hypervisor.framework/libkrun MicroVM driver; Docker Desktop 29.8.2; Podman not used.
  • One isolated local gateway on port 27670 with a SQLite store. The driver was changed in gateway.toml between restarts. The Docker phase ran under the local Docker Desktop user against the same isolated store; the VM disk remained in the isolated VM state directory.

Logs

2026-10-20T22:34:40.001901Z  WARN reconcile{otel.name="reconcile.sandboxes" driver.name=docker backend_count=0 store_count=3}: openshell_server::compute: Retained sandbox resource disappeared from the compute driver sandbox_id=<sandbox-id> sandbox_name=keep2 phase=Stopped
2026-10-20T22:35:40.017079Z  INFO reconcile{otel.name="reconcile.sandboxes" driver.name=docker backend_count=0 store_count=2}: openshell_server::compute: Removing sandbox from store after it disappeared from the compute driver snapshot sandbox_id=<sandbox-id> sandbox_name=keep2 age_secs=407
Error:   × code: 'Some requested entity was not found', message: "sandbox not found"

The last line is openshell sandbox start keep2 after switching back to VM. The old VM overlay disk was still present. The test used keep2 because the first, echo-only keep sandbox entered Completed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    state:triage-neededOpened without agent diagnostics and needs triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions