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

  1. Run `lite down` — it restores ~/.claude/settings.json from the backup and deletes the backup — then retry `lite up`
  2. Before forcing anything, confirm no other `lite up` is alive: `pgrep -af 'lite up'`
  3. 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

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


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/ef0f3ef8a4591eea. Report an issue: GitHub.