data) is the file_system_id everywhere in the sandbox API.
Mount at Creation
Pass one or more mounts when creating the sandbox. The mounts are ready before the sandbox is reported as running.- CLI
- Python
- TypeScript
- HTTP
-f/--filesystem takes <name>[@<snapshot-id>]:<mount-path>[:<opts>] and can be repeated. <opts> is a comma-separated list of ro (read-only) and/or prefetch; @<snapshot-id> pins the mount to a permanent snapshot and requires ro — see Pinned mounts:Create the filesystem first (
tl fs create <name>). Mounting a name that does not exist fails the sandbox — see Errors.Mount rules
Mount Options
All options are per mount and default to off.Read-only
read_only mounts the filesystem read-only. Writes inside the guest fail with EROFS. Enforcement is defense-in-depth: the storage credential minted for the mount carries no write scope, the host proxy filters writes, and the guest mount itself is read-only.
Read-only is fail-closed: the sandbox is only placed on executor fleets that can enforce it, so a read_only mount can never silently degrade to read-write. On fleets that have not yet been updated, a sandbox requesting a read-only mount will not be placed.
Prefetch
prefetch downloads the filesystem’s full tree in the background after the mount is ready. The mount is usable immediately — reads stream in lazily in the meantime — and once the prefetch completes, reads no longer touch the network. Prefetch is best-effort: it never blocks mount readiness and never fails the sandbox. On older fleets it is skipped silently.
- CLI
- Python
- TypeScript
- HTTP
Ownership
Every mount is reachable by every user inside the sandbox — root and the image’s default user alike — with ordinary file permission bits deciding access from there. Whatowner controls is whose files they appear to be: every file in the mount presents one owner, which is what ls -l shows and what non-world permission bits are checked against. In particular, on a writable mount only the presented owner (and root) can write.
By default the presented owner is the image’s tl-user account when the image has one — Tensorlake base images do — and root otherwise. That default is what you want until you build a custom image with its own user: with files presented as root’s, that user can read world-readable files (like mode-755 directories and 644 files) but cannot write. Set owner to fix that:
- Python
- TypeScript
- HTTP
- CLI
NAME, UID, NAME:GROUP, or UID:GID — for example agent, 1001, or 1001:1001. A named user or group is resolved against the sandbox image’s own user database when the mount attaches and must exist in the image; a numeric id is used as-is and needs no user database entry. tl sbx fs ls shows the spec as owner=agent in the mount’s options.
Two failure modes to know about: a malformed spec (empty parts, more than one :, an id that does not fit 32 bits) is rejected with 400 — the SDKs and CLI reject it client-side before any request — while a well-formed name that does not exist in the image can only be discovered inside the guest, so it fails the sandbox after acceptance with an error_details message naming the unresolvable user, the same shape as mounting a nonexistent filesystem.
Like read-only and pins, owners are fail-closed: an owner-bearing mount is only placed on executor fleets that enforce it, so it can never silently present the wrong owner. On fleets that have not yet been updated, a sandbox requesting an owner-bearing mount will not be placed.
Pinned mounts
A plain mount — read-only or not — follows the live filesystem: pushes and autosave checkpoints from anywhere become visible in the sandbox.snapshot_id pins the mount to one permanent snapshot instead. A pinned mount serves exactly the files captured in that snapshot and never follows the filesystem head, no matter how the filesystem advances afterward, so an entire fleet of sandboxes can mount one immutable state.
Pins reference permanent snapshots: the ones created with tl fs snapshot (or a message-bearing tl fs push -m) and listed under Snapshots in tl fs history:
read_only — the snapshot is immutable, and the server rejects a snapshot_id without read_only with 400. The SDKs and CLI reject the combination client-side before any request is made.
- CLI
- Python
- TypeScript
- HTTP
<name>@<snapshot-id>; quote the mount spec so the shell never splits it.tl sbx fs ls shows a pinned mount as skills@<snapshot-id> in the same <name>@<snapshot-id> syntax.
Like read-only, pinning is fail-closed: a sandbox with a pinned mount is only placed on executor fleets that enforce the pin, so it can never silently degrade to mounting the live filesystem. On fleets that have not yet been updated, a sandbox requesting a pinned mount will not be placed.
Two guardrails to know about:
- Pinning a snapshot that does not exist on the filesystem — including an ephemeral autosave id, which cannot be pinned — fails the sandbox with
FileSystemSnapshotNotFound; see Errors. - Deleting a snapshot with live pinned mounts is refused:
tl fs delete-snapshotreturns a409naming the pin count. Terminate the sandboxes or detach the pinned mounts first.
Mount on a Warm-Pool Claim
Pools keep containers pre-booted without filesystems; mounts belong to the claim, not the pool. Pass the samefile_systems when claiming, and the mounts are ready before the claimed sandbox is reported as running.
- Python
- TypeScript
- HTTP
Attach and Detach at Runtime
A running sandbox can attach and detach filesystems without restarting. Attach accepts the same per-mount options as creation, including snapshot pins.- CLI
- Python
- TypeScript
- HTTP
400— the mount is invalid (for example asnapshot_idwithoutread_only, or a malformedownerspec), or the sandbox runs on an executor fleet without filesystem (or snapshot-pin, or mount-owner) support. In the fleet case, recreate the sandbox to mount filesystems.409— the mount path is already in use, the sandbox is not running, or the sandbox’s executor is momentarily unresolvable (for example during a reconnect window). The last case is transient: retry shortly.
Errors
Mounting a filesystem that does not exist fails sandbox creation with HTTP422:
snapshot_id does not exist on the filesystem — or names an ephemeral autosave rather than a permanent snapshot — fails the same way, with reason FileSystemSnapshotNotFound:
tl fs history skills and pin one from its Snapshots section.
An owner naming a user or group that does not exist in the sandbox image fails the same way: the spec’s shape is validated up front (a malformed spec is a synchronous 400), but the name itself can only be resolved against the image’s user database inside the guest, so the sandbox fails after acceptance with an error_details message naming the unresolvable user. Use a numeric UID[:GID] spec to avoid depending on the image’s user database entirely.
Sharing Across Sandboxes
The same filesystem can be mounted by multiple sandboxes in one project concurrently. Writes from one sandbox become visible to the others as autosave checkpoints replicate — see Concurrent Writes for the merge semantics and Distribute Files for rolling out shared assets to a fleet of sandboxes with read-only mounts.Related Guides
Filesystems
Durable, versioned filesystems: create, push, snapshot, and time-travel.
Read-only Mounts
Pinned and following mounts for fixed inputs and shared assets.
Sandbox Pools
Pre-warm sandboxes and mount filesystems at claim time.
File Operations
Copy, read, and write files on the sandbox’s ephemeral root disk.