{"record":{"id":"cc90b9f8f90b6be3","repo":"zylon-ai/private-gpt","slug":"unsupported-semaphore-mode-mode-r-available","errorCode":null,"errorMessage":"Unsupported semaphore mode: {mode!r}. Available: {', '.join(sorted(_PROVIDERS))}","messagePattern":"Unsupported semaphore mode: (.+?)\\. Available: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"private_gpt/components/concurrency/registry.py","lineNumber":76,"sourceCode":"    \"redis\": _redis_semaphore_provider,\n    \"memory\": _memory_semaphore_provider,\n}\n\n\ndef register_semaphore_manager(name: str, provider: SemaphoreManagerProvider) -> None:\n    _PROVIDERS[name] = provider\n\n\ndef create_semaphore_manager(\n    settings: Settings | None = None,\n    max_concurrency: int | None = None,\n    queue_key: str | None = None,\n) -> SemaphoreManager:\n    settings = settings or get_global_injector().get(Settings)\n    mode = settings.semaphore.mode\n    provider = _PROVIDERS.get(mode)\n    if provider is None:\n        raise ValueError(\n            f\"Unsupported semaphore mode: {mode!r}. \"\n            f\"Available: {', '.join(sorted(_PROVIDERS))}\"\n        )\n    return provider(settings, max_concurrency, queue_key)\n","sourceCodeStart":58,"sourceCodeEnd":81,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/concurrency/registry.py#L58-L81","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set semaphore.mode to one of the modes printed in the error message (built-ins: 'redis' or 'memory')","Check for casing/whitespace typos in the config value; matching is exact, not normalized","If you use a custom backend, ensure register_semaphore_manager(name, provider) runs (import the plugin module) before create_semaphore_manager is called","If you need Redis, confirm the redis extra/dependencies are installed so the redis provider stays registered"],"exampleFix":"# before\nsemaphore:\n  mode: local  # ValueError: Unsupported semaphore mode: 'local'\n\n# after\nsemaphore:\n  mode: memory","handlingStrategy":"validation","validationCode":"from private_gpt.components.concurrency.registry import _PROVIDERS\nmode = settings.semaphore.mode\nassert mode in _PROVIDERS, f\"bad semaphore.mode {mode!r}; pick from {sorted(_PROVIDERS)}\"","typeGuard":null,"tryCatchPattern":"try:\n    manager = create_semaphore_manager(settings=settings)\nexcept ValueError as e:\n    if 'Unsupported semaphore mode' in str(e):\n        manager = create_semaphore_manager(\n            settings=settings.model_copy(deep=True)\n        )  # fix settings first; do not silently default","preventionTips":["Validate semaphore.mode at app startup against the registered provider names and fail fast","Use an enum/choices constraint for the config field so invalid values are rejected at load time","Import custom provider modules before any create_semaphore_manager call"],"tags":["configuration","concurrency","semaphore","registry"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}