{"record":{"id":"1a7458cf94f2ccf6","repo":"dotnet/efcore","slug":"the-specified-commandtimeout-value-value-is","errorCode":null,"errorMessage":"The specified 'CommandTimeout' value '{value}' is not valid. It must be a positive number.","messagePattern":"The specified 'CommandTimeout' value '(.+?)' is not valid\\. It must be a positive number\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalOptionsExtension.cs","lineNumber":169,"sourceCode":"    }\n\n    /// <summary>\n    ///     The command timeout, or <see langword=\"null\" /> if none has been set.\n    /// </summary>\n    public virtual int? CommandTimeout\n        => _commandTimeout;\n\n    /// <summary>\n    ///     Creates a new instance with all options the same as for this instance, but with the given option changed.\n    ///     It is unusual to call this method directly. Instead use <see cref=\"DbContextOptionsBuilder\" />.\n    /// </summary>\n    /// <param name=\"commandTimeout\">The option to change.</param>\n    /// <returns>A new instance with the option changed.</returns>\n    public virtual RelationalOptionsExtension WithCommandTimeout(int? commandTimeout)\n    {\n        if (commandTimeout is < 0)\n        {\n            throw new InvalidOperationException(RelationalStrings.InvalidCommandTimeout(commandTimeout));\n        }\n\n        var clone = Clone();\n\n        clone._commandTimeout = commandTimeout;\n\n        return clone;\n    }\n\n    /// <summary>\n    ///     The maximum number of statements that will be included in commands sent to the database\n    ///     during <see cref=\"DbContext.SaveChanges()\" /> or <see langword=\"null\" /> if none has been set.\n    /// </summary>\n    public virtual int? MaxBatchSize\n        => _maxBatchSize;\n\n    /// <summary>\n    ///     Creates a new instance with all options the same as for this instance, but with the given option changed.","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalOptionsExtension.cs#L151-L187","documentation":"RelationalOptionsExtension.WithCommandTimeout guards its input: a negative value is rejected (commandTimeout is < 0). null means 'unset' and is allowed, and 0 is permitted by the guard (the message wording 'positive number' is looser than the code). The exception is thrown eagerly when the option is set, not at query time.","triggerScenarios":"Calling optionsBuilder.UseXxx(...).CommandTimeout(-5), or RelationalOptionsExtension.WithCommandTimeout(-1) directly; computing the timeout from configuration and feeding a negative parsed value.","commonSituations":"Parsing CommandTimeout from an environment variable / appsettings that can be negative or unset (parsed as -1); sign errors in arithmetic; unit tests injecting bad values.","solutions":["Pass null to clear the timeout, or a non-negative int (the guard accepts 0).","Validate user-supplied input (env var, config) before passing it: coerce negatives to null or a sensible default.","If you meant 'unlimited'/default, pass null rather than a sentinel like -1."],"exampleFix":"// before\nvar timeout = int.Parse(config[\"CommandTimeout\"]!); // could be -1\noptionsBuilder.UseSqlServer(conn).CommandTimeout(timeout);\n\n// after\nvar raw = config[\"CommandTimeout\"];\nvar timeout = int.TryParse(raw, out var t) && t >= 0 ? t : (int?)null;\noptionsBuilder.UseSqlServer(conn).CommandTimeout(timeout);","handlingStrategy":"validation","validationCode":"// Coerce user-supplied timeout to null-or-non-negative before setting the option.\nstatic int? SafeCommandTimeout(string? raw)\n    => int.TryParse(raw, out var v) && v >= 0 ? v : (int?)null;","typeGuard":"static bool IsValidCommandTimeout(int? value) => value is null || value >= 0;","tryCatchPattern":null,"preventionTips":["Validate config/env values (env vars, appsettings) before passing to CommandTimeout.","Use null to express 'unset/default' rather than sentinels like -1.","Centralize options construction so timeouts flow through one validated helper."],"tags":["configuration","options","timeouts","relational"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}