bytedance/deer-flow · critical · SystemExit

GATEWAY_WORKERS={workers} requires database.backend='postgre

Error message

GATEWAY_WORKERS={workers} requires database.backend='postgres', but database.backend is '{backend}'. SQLite cannot support concurrent multi-process access. Set GATEWAY_WORKERS=1 or switch to Postgres.

What it means

SystemExit raised at startup when GATEWAY_WORKERS>1 but database.backend is not 'postgres'. SQLite cannot support concurrent multi-process access (single-writer, file-lock semantics), so N worker processes against one sqlite file would corrupt or serialize; the gate restricts multi-worker mode to Postgres.

Source

Thrown at backend/app/gateway/deps.py:112

    if multi_instance_requested and backend != "postgres":
        raise SystemExit(f"scheduler.multi_instance=true requires database.backend='postgres'. database.backend is '{backend}'. Set scheduler.multi_instance=false or configure Postgres.")
    if multi_instance_requested and run_events_backend != "db":
        raise SystemExit(f"scheduler.multi_instance=true requires run_events.backend='db'. run_events.backend is '{run_events_backend}'. Set scheduler.multi_instance=false or configure run_events.backend: db.")
    if multi_instance_requested and (run_ownership is None or not run_ownership.heartbeat_enabled):
        raise SystemExit("scheduler.multi_instance=true requires run_ownership.heartbeat_enabled=true so peer runs retain a valid lease. Set scheduler.multi_instance=false or enable run ownership heartbeats.")

    if workers <= 1:
        return

    if config.scheduler.enabled and not multi_instance_scheduler:
        raise SystemExit(f"GATEWAY_WORKERS={workers} cannot run with scheduler.enabled=true because each worker starts its own scheduler. Set GATEWAY_WORKERS=1, scheduler.multi_instance=true, or scheduler.enabled=false.")

    if _browser_tools_enabled_in_config(config):
        raise SystemExit(browser_multi_worker_error(workers))

    if backend != "postgres":
        raise SystemExit(f"GATEWAY_WORKERS={workers} requires database.backend='postgres', but database.backend is '{backend}'. SQLite cannot support concurrent multi-process access. Set GATEWAY_WORKERS=1 or switch to Postgres.")

    if run_events_backend != "db":
        raise SystemExit(
            f"GATEWAY_WORKERS={workers} requires run_events.backend='db', but run_events.backend is '{run_events_backend}'. "
            "Memory and JSONL event stores are process-local, so delivery receipt singleton guarantees cannot hold across workers. "
            "Set GATEWAY_WORKERS=1 or configure run_events.backend: db."
        )

    if run_ownership is None or not run_ownership.heartbeat_enabled:
        raise SystemExit(
            f"GATEWAY_WORKERS={workers} requires run_ownership.heartbeat_enabled=true. "
            "Without heartbeat, every run has a NULL lease, so reconciliation "
            "treats all inflight runs as orphans — Worker B would kill Worker A's "
            "live runs on every rolling update or scale-up. "
            "Set run_ownership.heartbeat_enabled=true in config.yaml."
        )

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Set GATEWAY_WORKERS=1
  2. Or migrate to database.backend: postgres with a valid shared Postgres URL
  3. Restart the Gateway

Example fix

# config.yaml
# before
database:
  backend: sqlite
# after
database:
  backend: postgres
  url: postgresql+asyncpg://user:pass@host/deerflow
Defensive patterns

Strategy: validation

Validate before calling

workers = int(os.environ.get("GATEWAY_WORKERS", "1"))
cfg = load_config()
assert not (workers > 1 and cfg.database.backend != "postgres"), "multi-worker needs postgres"

Prevention

When it happens

Trigger: GATEWAY_WORKERS>1 with database.backend: sqlite (or memory) in config.yaml; reached after the scheduler and browser-tool checks pass.

Common situations: Bumping GATEWAY_WORKERS on a dev-default sqlite config for a load test; moving a compose file to replicas without migrating the database; mis-set DATABASE_URL leaving backend resolution at sqlite.

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/c8fe0b75d7cdc8f9. Report an issue: GitHub.