PrefectHQ/fastmcp · error · StateFileError

CLI state is invalid

Error message

CLI state is invalid: {path.name}

What it means

StateFileError raised by read_state when the state file's contents fail pydantic validation (ValidationError) or JSON parsing (ValueError). The file exists but is not a valid instance of the expected versioned model, so the CLI treats the state as unusable. The original error is deliberately suppressed (from None).

Solutions

  1. Delete or move aside the corrupt file and re-run the command to regenerate it (mv session.json session.json.bak)
  2. Check fastmcp version changes — if you downgraded/upgraded, clear the old state
  3. Do not hand-edit state files; use CLI commands to modify state
  4. Restore from backup if the state held credentials you need

Example fix

// before
$ cat ~/.fastmcp/state/session.json
{"origin": "https://api"  <truncated>
// after
$ mv ~/.fastmcp/state/session.json ~/.fastmcp/state/session.json.bak
$ fastmcp login   # rewrites valid state
Defensive patterns

Strategy: validation

Validate before calling

import json
from pathlib import Path

def state_file_parses(path: Path) -> bool:
    try:
        json.loads(path.read_text(encoding="utf-8"))
        return True
    except (json.JSONDecodeError, UnicodeDecodeError):
        return False

Try / catch

try:
    state = load(state_path)
except StateFileError as exc:
    if "invalid" in str(exc):
        state_path.rename(state_path.with_suffix(".json.bak"))
        state = load(state_path)   # regenerate fresh state
    else:
        raise

Prevention

When it happens

Trigger: Calling read_state (via load) when path.read_text returns content that is not parseable JSON or does not match the expected model schema — truncated file, hand-edited JSON, empty file, or state written by an incompatible older/newer fastmcp version.

Common situations: Power loss or crash mid-write leaving a truncated file (older fastmcp without atomic writes); manual editing of state JSON; upgrading/downgrading fastmcp so the schema changed; encoding corruption.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/4fa36cf898ab22e0. Report an issue: GitHub.

Appendix: source

Thrown at fastmcp_slim/fastmcp/cli/deploy/state.py:164

    path: Path,
    model: type[ModelT],
    *,
    secret: bool = False,
) -> ModelT | None:
    """Read and validate a versioned JSON state file."""
    if not path.exists():
        return None
    if path.is_symlink():
        raise StateFileError(f"CLI state must not be a symbolic link: {path.name}")

    if secret:
        _restrict_access(path.parent, directory=True)
        _restrict_access(path)

    try:
        return model.model_validate_json(path.read_text(encoding="utf-8"))
    except (ValidationError, ValueError):
        raise StateFileError(f"CLI state is invalid: {path.name}") from None
    except OSError as exc:
        raise StateFileError(f"Could not read CLI state: {path.name}") from exc


def write_state(path: Path, data: dict[str, Any]) -> None:
    """Write JSON through a restricted temporary file and atomic replacement."""
    _prepare_directory(path.parent)
    payload = (json.dumps(data, indent=2, sort_keys=True) + "\n").encode()
    descriptor: int | None = None
    temporary_path: Path | None = None

    try:
        descriptor, temporary_name = tempfile.mkstemp(
            dir=path.parent,
            prefix=f".{path.name}.",
            suffix=".tmp",
        )
        temporary_path = Path(temporary_name)

View on GitHub (pinned to 1f02114297)