BerriAI/litellm · error · UpError
{BACKUP_PATH} already exists -- `lite up` looks like it's al
Error message
{BACKUP_PATH} already exists -- `lite up` looks like it's already running (or crashed without cleanup). Run `lite down` first. What it means
Raised by `lite up` when it is about to snapshot ~/.claude/settings.json but the backup file ~/.litellm/claude_settings_backup.json (BACKUP_PATH) already exists. The backup doubles as a run marker: a live `up` keeps it until it restores on exit, so an existing file means another `up` is running or a previous one died without cleanup (kill -9, closed terminal, crash). Refusing to overwrite it protects the original Claude settings from being lost.
Source
Thrown at litellm/proxy/client/cli/commands/up.py:208
@click.pass_context
def up(ctx: click.Context) -> None:
"""Route every Claude Code session through your LiteLLM proxy until stopped.
Patches ~/.claude/settings.json so Claude Code picks up the proxy on its own
next startup, from any terminal -- no need to launch it through `lite`.
Press Ctrl-C to stop and restore your original settings. Assumes the proxy
is already running (this does not start one for you). Cursor is not
supported: it has no equivalent file-based config to patch.
"""
base_url: Final = ctx.obj["base_url"]
try:
_ensure_fresh_login(ctx)
api_key: Final = resolve_api_key(ctx)
verify_proxy_key(base_url, api_key)
if BACKUP_PATH.exists():
raise UpError(
f"{BACKUP_PATH} already exists -- `lite up` looks like it's already "
"running (or crashed without cleanup). Run `lite down` first."
)
api_key_helper: Final = resolve_api_key_helper(base_url)
original_existed: Final = CLAUDE_SETTINGS_PATH.exists()
original_settings: Final = load_json_or_empty(CLAUDE_SETTINGS_PATH)
write_backup(
BackupRecord(
existed=original_existed,
content=original_settings if original_existed else None,
)
)
CLAUDE_SETTINGS_PATH.parent.mkdir(exist_ok=True)
merged: Final = merge_claude_settings(original_settings, base_url, api_key_helper)
with open(CLAUDE_SETTINGS_PATH, "w") as f:
json.dump(merged, f, indent=2)View on GitHub (pinned to 77b7c6c40c)
Solutions
- Run `lite down` — it restores ~/.claude/settings.json from the backup and deletes the backup — then retry `lite up`
- Before forcing anything, confirm no other `lite up` is alive: `pgrep -af 'lite up'`
- If `lite down` says nothing to restore but the file persists, inspect ~/.litellm/claude_settings_backup.json, hand-restore its `content` into ~/.claude/settings.json if it holds your real settings, then delete the backup file
Example fix
# before lite up # UpError: /home/me/.litellm/claude_settings_backup.json already exists ... # after lite down # restores original settings, removes backup lite up
Defensive patterns
Strategy: validation
Validate before calling
import subprocess, sys
from pathlib import Path
backup = Path.home() / ".litellm" / "claude_settings_backup.json"
if backup.exists():
print("stale `lite up` state detected — restoring before start")
raise SystemExit(subprocess.call(["lite", "down"]))
raise SystemExit(subprocess.call(["lite", "up"])) Try / catch
try:
start_lite_up()
except UpError as e: # or click.ClickException when driving the CLI
if "already exists" in str(e):
run_lite_down_then_retry()
raise Prevention
- Stop `lite up` with Ctrl-C or SIGTERM (never kill -9) so its atexit restore removes the backup
- Run `lite down` as the first recovery step on any box where `up` died uncleanly
- Before starting `up`, check for a running instance: pgrep -af 'lite up'
When it happens
Trigger: Starting a second `lite up` while one is already running; a previous `up` killed with SIGKILL or by a terminal/SSH disconnect so its atexit/SIGTERM restore never ran; leftover backup from an earlier crashed session; reboot or sleep killing the foreground `up` process.
Common situations: tmux/SSH session was killed while `up` was in the foreground; CI box reused across runs after a hard timeout; developer forgot a `lite up` running in another terminal; machine crashed mid-session.
Related errors
- User role is required for CLI JWT login
- Could not find `lite` on your PATH. Claude Code's apiKeyHelp
- No fresh LiteLLM login found for this proxy. Run `lite login
- Login did not produce a usable token; cannot start `lite up`
- You must be a LiteLLM Enterprise user to use this feature. I
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/ef0f3ef8a4591eea.
Report an issue: GitHub.