zylon-ai/private-gpt · error · ValueError

Unsupported semaphore mode: {mode!r}. Available: {', '.join(

Error message

Unsupported semaphore mode: {mode!r}. Available: {', '.join(sorted(_PROVIDERS))}

What it means

Raised by create_semaphore_manager when settings.semaphore.mode does not match any registered provider. The provider table (_PROVIDERS) is populated at import time with 'redis' and 'memory', plus anything added via register_semaphore_manager. The message interpolates the offending mode and the sorted list of registered modes, so a mismatch is almost always a settings typo or a stale custom registration.

Source

Thrown at private_gpt/components/concurrency/registry.py:76

    "redis": _redis_semaphore_provider,
    "memory": _memory_semaphore_provider,
}


def register_semaphore_manager(name: str, provider: SemaphoreManagerProvider) -> None:
    _PROVIDERS[name] = provider


def create_semaphore_manager(
    settings: Settings | None = None,
    max_concurrency: int | None = None,
    queue_key: str | None = None,
) -> SemaphoreManager:
    settings = settings or get_global_injector().get(Settings)
    mode = settings.semaphore.mode
    provider = _PROVIDERS.get(mode)
    if provider is None:
        raise ValueError(
            f"Unsupported semaphore mode: {mode!r}. "
            f"Available: {', '.join(sorted(_PROVIDERS))}"
        )
    return provider(settings, max_concurrency, queue_key)

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Set semaphore.mode to one of the modes printed in the error message (built-ins: 'redis' or 'memory')
  2. Check for casing/whitespace typos in the config value; matching is exact, not normalized
  3. If you use a custom backend, ensure register_semaphore_manager(name, provider) runs (import the plugin module) before create_semaphore_manager is called
  4. If you need Redis, confirm the redis extra/dependencies are installed so the redis provider stays registered

Example fix

# before
semaphore:
  mode: local  # ValueError: Unsupported semaphore mode: 'local'

# after
semaphore:
  mode: memory
Defensive patterns

Strategy: validation

Validate before calling

from private_gpt.components.concurrency.registry import _PROVIDERS
mode = settings.semaphore.mode
assert mode in _PROVIDERS, f"bad semaphore.mode {mode!r}; pick from {sorted(_PROVIDERS)}"

Try / catch

try:
    manager = create_semaphore_manager(settings=settings)
except ValueError as e:
    if 'Unsupported semaphore mode' in str(e):
        manager = create_semaphore_manager(
            settings=settings.model_copy(deep=True)
        )  # fix settings first; do not silently default

Prevention

When it happens

Trigger: Calling create_semaphore_manager() (directly or through DI wiring) with settings.semaphore.mode set to a string not in {'redis', 'memory'}, e.g. 'Redis', 'local', 'inmemory', or 'memcached'. Also occurs if a custom provider is registered under a different name than the one the config uses, or if a plugin that registers the provider was never imported.

Common situations: Typo or wrong casing in the semaphore.mode config value (e.g. 'Memory' vs 'memory'); copying a config from an older/newer version where mode names changed; expecting a distributed backend that is not built in; forgetting to import the module that calls register_semaphore_manager for a custom backend.

Related errors


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