zylon-ai/private-gpt · critical · ValueError

scheduler.chat.mode={self.scheduler.chat.mode!r} requires st

Error message

scheduler.chat.mode={self.scheduler.chat.mode!r} requires stream.broker=redis because API and chat worker processes must share stream state.

What it means

Startup-time ValueError from the root Settings model_validator: any non-'local' chat scheduler mode (i.e. 'arq') requires stream.broker == 'redis'. In arq mode the API process and the chat worker are separate processes that must share streaming state, which is only possible through the Redis stream broker; the in-memory broker cannot bridge them.

Source

Thrown at private_gpt/settings/settings.py:1888

        if self.scheduler.tools.mode not in {"local", "celery"}:
            raise ValueError(
                f"Unsupported scheduler.tools.mode={self.scheduler.tools.mode!r}. "
                "Supported tool scheduler modes are 'local' and 'celery'."
            )

        if self.scheduler.tools.mode == "celery" and self.scheduler.chat.mode != "arq":
            raise ValueError(
                f"scheduler.tools.mode={self.scheduler.tools.mode!r} requires "
                "scheduler.chat.mode='arq' so tool callbacks can resume shared "
                "chat state."
            )

        if self.scheduler.chat.mode == "local":
            return self

        if self.stream.broker != "redis":
            raise ValueError(
                f"scheduler.chat.mode={self.scheduler.chat.mode!r} requires stream.broker=redis "
                "because API and chat worker processes must share stream state."
            )

        return self


"""
This is visible just for DI or testing purposes.

Use dependency injection or `settings()` method instead.
"""
unsafe_settings = load_active_settings()

"""
This is visible just for DI or testing purposes.

Use dependency injection or `settings()` method instead.

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Set stream.broker: redis when scheduler.chat.mode is arq.
  2. Ensure Redis connection settings (host/port/credentials) are configured and reachable from both API and worker.
  3. Or revert scheduler.chat.mode to local if you only have a single process.
  4. Apply the change in every environment that enables arq mode, then restart API and workers together.

Example fix

# before
scheduler:
  chat:
    mode: arq
stream:
  broker: memory
# after
scheduler:
  chat:
    mode: arq
stream:
  broker: redis
Defensive patterns

Strategy: validation

Validate before calling

chat_mode = cfg.get('scheduler', {}).get('chat', {}).get('mode')
stream_broker = cfg.get('stream', {}).get('broker')
assert chat_mode == 'local' or stream_broker == 'redis', 'arq chat requires redis stream broker'

Type guard

const arqNeedsRedis = (cfg: { scheduler: { chat: { mode: string } }; stream: { broker: string } }): boolean =>
  cfg.scheduler.chat.mode !== 'arq' || cfg.stream.broker === 'redis';

Prevention

When it happens

Trigger: settings.yaml with scheduler.chat.mode: arq while stream.broker is left at its default (in-memory) or explicitly set to a non-redis value; enabling the arq chat worker without reconfiguring streaming.

Common situations: Scaling out to worker processes and forgetting the streaming dependency; per-profile YAMLs where the arq profile lacks the stream override; local dev defaults copied into a distributed deployment.

Related errors


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/f3cff7859231d122. Report an issue: GitHub.