Troubleshooting & recovery
Most problems fall into one loop: diagnose with status / tail, recover with
stop + up. Because stop keeps the worktree, branch, and metadata, you can
rebuild a broken container without losing any work.
flowchart TD
P[Something's wrong] --> S[ffleet status SLUG]
S --> T[ffleet tail SLUG]
T --> D{What is it?}
D -->|agent exited / container broken| R[ffleet stop SLUG → ffleet up SLUG]
D -->|config change needed| C[edit ffleet.toml → stop → up]
D -->|identity change needed| X[ffleet remove SLUG → ffleet up SLUG …]
R --> OK[Running again, work preserved]
C --> OK
Step 1: diagnose
ffleet status SLUG— is the container up? is the agent live or exited? is it blocked? This is the first look.ffleet tail SLUG— the last lines of the agent's transcript (--lines Nfor more). Shows what the agent was doing or the error it hit.ffleet ls— confirm the environment exists and its overall state.
Step 2: recover
The agent crashed or the container is broken
Rebuild it from saved config — your worktree and session survive:
$ ffleet stop my-feature # remove the broken container (keeps everything else)
$ ffleet up my-feature # rebuild from config, resume the session
Often you can skip straight to ffleet up my-feature — up detects a dead agent
or a missing container and rebuilds. Use the explicit stop first when you want
a guaranteed-clean container.
A config change isn't taking effect
If you changed image, a mount, hosts, or the env file and don't see it, revive
to refresh config-derived settings:
$ ffleet stop my-feature && ffleet up my-feature
If the setting you changed is an identity setting (branch, git-mode, agent, worktree mode), a revive won't pick it up — you must recreate:
$ ffleet remove my-feature # deletes worktree + ffleet-created branch — check for unpushed work!
$ ffleet up my-feature --git-mode … …
remove warns when the worktree still holds uncommitted changes or untracked
files, or commits that no remote branch contains. It reads only your local
remote-tracking refs (origin/…) and never fetches, so it stays fast and works
offline — but if those refs are stale, it can warn about commits you have
already pushed. Run git fetch --prune and re-check when a warning looks wrong.
See config precedence for which bucket a setting is in.
Container won't become ready in time
First-time image pulls or heavy setup can exceed the default readiness wait. Raise it:
$ ffleet up my-feature --wait-timeout 900
Can't attach
ffleet up SLUGattaches when the agent is live and relaunches it if not.ffleet up SLUG --peekattaches only if it's already live and never relaunches — useful to check without side effects.- To detach cleanly once attached, use tmux
Ctrl-BthenD.
Garbled characters or wrong colors after attaching
Attaching runs docker exec -it <env> tmux -u attach. docker exec hard-codes
TERM=xterm and does not inherit your terminal, so Forge Fleet forwards the
host's TERM, LANG, and COLORTERM into the exec — that keeps the tmux client
matched to your real terminal instead of emitting mismatched escape sequences
(stray/garbled characters). If your host TERM has no terminfo entry inside the
container (common for kitty/ghostty/wezterm/foot), it is downgraded to
xterm-256color so attach never fails with missing or unsuitable terminal.
tmux -u forces UTF-8 rendering regardless of the container locale.
If you still see garbled output or missing colors with a custom image, make sure the image provides the same defaults the bundled one bakes in:
- a UTF-8 locale (
LANG, e.g.en_US.UTF-8), - a broad terminfo database (
ncurses-term), - an
/etc/tmux.confwithdefault-terminal tmux-256color, truecolor, andallow-passthrough on.
When in doubt
stopis safe and reversible;removeis not. Reach forstopfirst.- Your work lives in the worktree and the saved session, not the container — so rebuilding the container is cheap.
- Still stuck? File an issue on ffleet-dist (see Feedback).