{"record":{"id":"2addffcaaa33b911","repo":"HangfireIO/Hangfire","slug":"timeout-argument-value-should-be-greater-than-zero","errorCode":null,"errorMessage":"Timeout argument value should be greater than zero.","messagePattern":"Timeout argument value should be greater than zero\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Hangfire.Core/DisableConcurrentExecutionAttribute.cs","lineNumber":30,"sourceCode":"// \n// You should have received a copy of the GNU Lesser General Public \n// License along with Hangfire. If not, see <http://www.gnu.org/licenses/>.\n\nusing System;\nusing System.Globalization;\nusing System.Linq;\nusing Hangfire.Annotations;\nusing Hangfire.Common;\nusing Hangfire.Server;\nusing Newtonsoft.Json;\n\nnamespace Hangfire\n{\n    public class DisableConcurrentExecutionAttribute : JobFilterAttribute, IServerFilter\n    {\n        public DisableConcurrentExecutionAttribute(int timeoutInSeconds)\n        {\n            if (timeoutInSeconds < 0) throw new ArgumentException(\"Timeout argument value should be greater than zero.\");\n\n            TimeoutSec = timeoutInSeconds;\n        }\n        \n        [JsonConstructor]\n        public DisableConcurrentExecutionAttribute(string resource, int timeoutSec)\n            : this(timeoutSec)\n        {\n            Resource = resource;\n        }\n\n        [CanBeNull]\n        public string Resource { get; }\n        public int TimeoutSec { get; }\n\n        public void OnPerforming(PerformingContext context)\n        {\n            var resource = GetResource(context.BackgroundJob.Job);","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/HangfireIO/Hangfire/blob/c236dd0f930f831ec151e436e138ddc429a02a72/src/Hangfire.Core/DisableConcurrentExecutionAttribute.cs#L12-L48","documentation":"DisableConcurrentExecutionAttribute's constructor (DisableConcurrentExecutionAttribute.cs:30) validates that the timeout (in seconds) is non-negative. A negative timeout is meaningless for a distributed lock acquisition and would produce invalid TimeSpan behavior, so an ArgumentException is thrown. Note: the message says 'greater than zero' but the check is '< 0', so 0 is permitted (meaning no wait / immediate fail).","triggerScenarios":"Applying [DisableConcurrentExecution(timeoutInSeconds)] with a negative value, e.g. [DisableConcurrentExecution(-1)].","commonSituations":"Config-driven timeout value parsed as negative due to a sign error or missing config default; arithmetic that subtracts producing a negative result.","solutions":["Use a non-negative timeout value (>= 0).","Validate configuration-sourced timeout values before applying the attribute.","Use a meaningful positive timeout (e.g. 30 or 60 seconds) to allow reasonable wait time for the lock."],"exampleFix":"// before\n[DisableConcurrentExecution(-5)]\npublic void ProcessJob(int id) { ... }\n\n// after\n[DisableConcurrentExecution(30)]\npublic void ProcessJob(int id) { ... }","handlingStrategy":"validation","validationCode":"if (timeoutInSeconds < 0)\n    throw new ArgumentOutOfRangeException(nameof(timeoutInSeconds),\n        \"Timeout must be non-negative.\");\n// then apply attribute or configure dynamically","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use non-negative timeout values for DisableConcurrentExecutionAttribute.","Validate config-sourced timeout values before applying.","Prefer a positive timeout (e.g. 30s) to allow reasonable lock wait time."],"tags":["concurrency","distributed-lock","argument-range","attribute"],"backgroundTag":null,"analyzedSha":"c236dd0f930f831ec151e436e138ddc429a02a72","analyzedAt":"2026-08-13T20:27:11.027Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}