{"record":{"id":"a5dc9746653738cd","repo":"zylon-ai/private-gpt","slug":"visibility-timeout-should-be-set-when-broker-or-ba","errorCode":null,"errorMessage":"Visibility timeout should be set when broker or backend is Redis","messagePattern":"Visibility timeout should be set when broker or backend is Redis","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"private_gpt/settings/settings.py","lineNumber":1163,"sourceCode":"                int(data[\"hard_time_limit\"]) if data[\"hard_time_limit\"] else None\n            )\n        if \"max_memory_per_child\" in data:\n            data[\"max_memory_per_child\"] = (\n                int(data[\"max_memory_per_child\"])\n                if data[\"max_memory_per_child\"]\n                else None\n            )\n        if \"visibility_timeout\" in data:\n            data[\"visibility_timeout\"] = (\n                int(data[\"visibility_timeout\"]) if data[\"visibility_timeout\"] else None\n            )\n        super().__init__(**data)\n\n    def validate_config(self) -> bool:\n        # Check if visibility timeout is set when broker or backend is redis\n        if self.broker_mode == \"redis\" or self.backend_mode == \"redis\":\n            if not self.visibility_timeout:\n                raise ValueError(\n                    \"Visibility timeout should be set when broker or backend is Redis\"\n                )\n\n        if self.soft_time_limit:\n            if self.hard_time_limit and self.soft_time_limit > self.hard_time_limit:\n                raise ValueError(\n                    \"Soft time limit should be less than or equal to hard time limit\"\n                )\n\n            if (\n                self.visibility_timeout\n                and self.visibility_timeout < self.soft_time_limit\n            ):\n                raise ValueError(\n                    \"Visibility timeout should be greater than soft time limit\"\n                )\n\n        if self.hard_time_limit:","sourceCodeStart":1145,"sourceCodeEnd":1181,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/settings/settings.py#L1145-L1181","documentation":"Config-validation ValueError from CelerySettings.validate_config: when broker_mode or backend_mode is 'redis', visibility_timeout must be set. With Redis, Celery's early-ack behavior can redeliver a task before it finishes, producing duplicates unless visibility_timeout exceeds the longest task; the validator therefore refuses Redis configs without it.","triggerScenarios":"settings.yaml (or env vars) with celery broker_mode: redis and/or backend_mode: redis but no visibility_timeout (or an explicit null/0 — the loader coerces falsy values to None). Switching the broker from rabbitmq to redis in an existing config that never had the key.","commonSituations":"Migrating from RabbitMQ to Redis for simpler ops and reusing the old YAML; adding a redis backend for result tracking; visibility_timeout set to 0 or empty string in env vars being coerced to None; copy-pasted minimal example configs.","solutions":["Set celery visibility_timeout in settings (seconds), e.g. visibility_timeout: 3600 — comfortably above your longest task.","If it is set but ignored, check the env/YAML value is not empty/0 (the loader maps falsy to None) and the key nesting matches the schema.","If you did not intend Redis, set broker_mode/backend_mode back to the intended non-redis value.","Restart the API and worker processes after fixing the config — validation runs at settings load."],"exampleFix":"# before (settings.yaml)\ncelery:\n  broker_mode: redis\n  backend_mode: redis\n# after\ncelery:\n  broker_mode: redis\n  backend_mode: redis\n  visibility_timeout: 7200","handlingStrategy":"validation","validationCode":"cfg = load_settings_profile('prod')\ncelery_cfg = cfg.get('celery', {})\nif 'redis' in (celery_cfg.get('broker_mode'), celery_cfg.get('backend_mode')):\n    assert int(celery_cfg.get('visibility_timeout') or 0) > 0, 'redis celery needs visibility_timeout'","typeGuard":"const redisNeedsVisibility = (c: { broker_mode?: string; backend_mode?: string; visibility_timeout?: number }): boolean =>\n  (c.broker_mode === 'redis' || c.backend_mode === 'redis') && !c.visibility_timeout;","tryCatchPattern":null,"preventionTips":["Add a pre-deploy config lint that enforces the visibility_timeout/redis invariant.","Keep a canonical Redis Celery block in config templates.","Re-validate with `python -c 'from private_gpt.settings.settings import Settings'` in CI."],"tags":["celery","redis","configuration","task-queue","startup"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}