Skip to main content
Three distinct primitives: snapshot marks a disk state in place, clone produces a brand-new independent box from an existing one, and export / import packs a box into a portable .boxlite archive. They are not interchangeable — the differences are in Parameters and Returns.

Which one do you need?

End to end: clone, export, import

The following walks through “write data -> clone -> export -> import -> verify data is preserved” end to end and is runnable as-is.
Note: box.snapshot is a property (getter) that returns a snapshot handle; its create/list/get/remove/restore methods are async and require await.

Parameters and Returns

Snapshots: box.snapshot.create / list / get / remove / restore

box.snapshot is a synchronous property on the Box that returns a SnapshotHandle. All of its methods are async.
create’s name is a keyword-only parameter: await box.snapshot.create(name="v1"). options is currently a placeholder SnapshotOptions() (an empty struct) and can usually be omitted.
SnapshotInfo fields (source sdks/python/src/snapshots.rs):

Clone: box.clone_box

Returns: a new Box (an independent disk copy). Cloning a running sandbox quiesces and resumes the source VM automatically; the cloned sandbox starts in a stopped state and starts automatically on its first exec.

Export: box.export

Returns: str — the full path of the generated .boxlite archive file.

Import: runtime.import_box

Note: import_box is called on the runtime object, not on a box. Returns: a new Box.

Node example (clone plus export/import)

The corresponding Node SDK methods are box.cloneBox(opts?, name?), box.export(dest, opts?), and runtime.importBox(archivePath, name?); the snapshot handle is reached via box.snapshot (create/list/get/remove/restore). Note the package name is @boxlite-ai/boxlite.

Troubleshooting

Startup fails: no hardware virtualization (environment constraint)

Snapshot, clone, and export all require the sandbox to start first, and starting a sandbox requires hardware virtualization:
  • Linux: requires KVM (/dev/kvm accessible, user in the kvm group). WSL2 also requires KVM enabled.
  • macOS: uses Apple’s Hypervisor.framework and does not need /dev/kvm.
  • Without virtualization, create/start fail with a standard exception (the process itself stays alive and can be caught with try/except and surfaced).

clone_box(...) / export(...) reports “source box unavailable” or disappears under auto_remove

If the source box is created with the default auto_remove=True, it may be reclaimed before the clone/export. For a source box used in snapshot/clone/export flows, pass auto_remove=False explicitly:

AttributeError: ... has no attribute 'remove' (calling remove on a box)

Removing a sandbox must be called on the runtime: await runtime.remove(box.id, force=True), not box.remove(). To list sandboxes, use runtime.list_info(), not runtime.list().

await box.info() errors / coroutine was never awaited

box.info() is a synchronous method; call box.info() directly and do not await it. It returns a BoxInfo, and the state is at box.info().state (a BoxStateInfo, whose field is named .status).

box.snapshot.create("v1") reports a missing keyword argument

create’s name is keyword-only and must be written as await box.snapshot.create(name="v1"); it cannot be passed positionally as create("v1").

restore behavior: stop first; the handle is invalidated

snapshot.restore has a few caveats:
  • You must stop the sandbox first: calling await box.snapshot.restore("v1") on a running sandbox raises RuntimeError: invalid state: Cannot restore snapshot while box is running. Stop the box first. (it is catchable with try/except, not a panic). Call await box.stop() first, then restore.
  • The handle is invalidated after stop: after stop(), calling exec on the old handle raises RuntimeError: stopped: Handle invalidated after stop(). Use runtime.get() to get a new handle.. Re-run box = await runtime.get(box.id) to obtain a fresh handle.
Limitation: restore does not guarantee a roll-back of disk contents. When you need a “clean environment”, prefer clone_box or export / import_box.

Removing a snapshot the “current disk depends on” raises RuntimeError

Calling snapshot.remove(name) on a snapshot the “current disk currently depends on” (for example, one you restored to) raises:
This is a catchable standard exception. Restore to a different snapshot first, or remove a snapshot that is not depended upon.

Image pull failure raises RuntimeError

A missing command or an image pull failure raises a standard RuntimeError (Python) / bare Error (Node), not BoxliteError. See Error Handling.