{"record":{"id":"4fa9377591ded3bc","repo":"zylon-ai/private-gpt","slug":"soft-time-limit-should-be-less-than-or-equal-to-ha","errorCode":null,"errorMessage":"Soft time limit should be less than or equal to hard time limit","messagePattern":"Soft time limit should be less than or equal to hard time limit","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"private_gpt/settings/settings.py","lineNumber":1169,"sourceCode":"                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:\n            if (\n                self.visibility_timeout\n                and self.visibility_timeout < self.hard_time_limit\n            ):\n                raise ValueError(\n                    \"Visibility timeout should be greater than hard time limit\"","sourceCodeStart":1151,"sourceCodeEnd":1187,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/settings/settings.py#L1151-L1187","documentation":"Config-validation ValueError from CelerySettings.validate_config: soft_time_limit must be <= hard_time_limit when both are set. Celery raises SoftTimeLimitExceeded inside the task at the soft limit so it can clean up, while the hard limit kills the worker process; an inversion of that ordering would make the soft signal useless, so the settings validator rejects it at startup.","triggerScenarios":"settings.yaml or env with soft_time_limit: 300 and hard_time_limit: 120; setting only one limit per environment (dev vs prod) and them drifting; unit confusion (seconds vs milliseconds) making soft appear larger.","commonSituations":"Ops tightening the hard limit in production without adjusting the soft limit; configs templated from examples with mismatched values; env var overrides applied to one limit only.","solutions":["Make soft_time_limit <= hard_time_limit (typical pattern: soft = 80-90% of hard), e.g. soft 240 / hard 300.","If the hard limit was lowered intentionally, lower the soft limit to match.","Audit both environments' overrides (YAML + env vars) — the effective pair must satisfy the invariant everywhere.","After editing, restart services so settings re-validate."],"exampleFix":"# before\ncelery:\n  soft_time_limit: 600\n  hard_time_limit: 300\n# after\ncelery:\n  soft_time_limit: 240\n  hard_time_limit: 300","handlingStrategy":"validation","validationCode":"soft, hard = cfg['celery'].get('soft_time_limit'), cfg['celery'].get('hard_time_limit')\nif soft and hard:\n    assert soft <= hard, f'soft ({soft}) must be <= hard ({hard})'","typeGuard":"const limitsOrdered = (c: { soft_time_limit?: number; hard_time_limit?: number }): boolean =>\n  c.soft_time_limit == null || c.hard_time_limit == null || c.soft_time_limit <= c.hard_time_limit;","tryCatchPattern":null,"preventionTips":["Derive soft_time_limit from hard_time_limit (e.g. 0.8x) in templates so they cannot invert.","Review both limits together in change requests.","Run the settings loader in CI for every environment overlay."],"tags":["celery","configuration","timeouts","task-queue","startup"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}