{"record":{"id":"065637ecda315907","repo":"dotnet/orleans","slug":"invalid-nameof-adonetstreamoptions-values-for-a-065637","errorCode":null,"errorMessage":"Invalid {nameof(AdoNetStreamOptions)} values for ADO.NET Streaming Provider '{name}': {nameof(options.VisibilityTimeout)} must be greater than zero.","messagePattern":"Invalid (.+?) values for ADO\\.NET Streaming Provider '(.+?)': (.+?) must be greater than zero\\.","errorType":"validation","errorClass":"OrleansConfigurationException","httpStatus":null,"severity":"error","filePath":"src/AdoNet/Orleans.Streaming.AdoNet/AdoNetStreamOptionsValidator.cs","lineNumber":30,"sourceCode":"    {\n        if (IsNullOrWhiteSpace(options.Invariant))\n        {\n            throw new OrleansConfigurationException($\"Invalid {nameof(AdoNetStreamOptions)} values for ADO.NET Streaming Provider '{name}': {nameof(options.Invariant)} is required.\");\n        }\n\n        if (IsNullOrWhiteSpace(options.ConnectionString) == (options.DataSource is null))\n        {\n            throw new OrleansConfigurationException($\"Invalid {nameof(AdoNetStreamOptions)} values for ADO.NET Streaming Provider '{name}': configure exactly one of {nameof(options.ConnectionString)} or {nameof(options.DataSource)}.\");\n        }\n\n        if (options.MaxAttempts < 0)\n        {\n            throw new OrleansConfigurationException($\"Invalid {nameof(AdoNetStreamOptions)} values for ADO.NET Streaming Provider '{name}': {nameof(options.MaxAttempts)} must be greater than zero.\");\n        }\n\n        if (options.VisibilityTimeout < TimeSpan.Zero)\n        {\n            throw new OrleansConfigurationException($\"Invalid {nameof(AdoNetStreamOptions)} values for ADO.NET Streaming Provider '{name}': {nameof(options.VisibilityTimeout)} must be greater than zero.\");\n        }\n\n        if (options.EvictionInterval < TimeSpan.Zero)\n        {\n            throw new OrleansConfigurationException($\"Invalid {nameof(AdoNetStreamOptions)} values for ADO.NET Streaming Provider '{name}': {nameof(options.EvictionInterval)} must be greater than zero.\");\n        }\n\n        if (options.ExpiryTimeout < TimeSpan.Zero)\n        {\n            throw new OrleansConfigurationException($\"Invalid {nameof(AdoNetStreamOptions)} values for ADO.NET Streaming Provider '{name}': {nameof(options.ExpiryTimeout)} must be greater than zero.\");\n        }\n\n        if (options.DeadLetterEvictionTimeout < TimeSpan.Zero)\n        {\n            throw new OrleansConfigurationException($\"Invalid {nameof(AdoNetStreamOptions)} values for ADO.NET Streaming Provider '{name}': {nameof(options.DeadLetterEvictionTimeout)} must be greater than zero.\");\n        }\n\n        if (options.EvictionBatchSize < 0)","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/AdoNet/Orleans.Streaming.AdoNet/AdoNetStreamOptionsValidator.cs#L12-L48","documentation":"Thrown by the ADO.NET streaming options validator when VisibilityTimeout is negative. VisibilityTimeout controls how long a message stays invisible to other consumers after dequeue. The check is `< TimeSpan.Zero`, so zero is accepted though the message says 'greater than zero' — zero would cause immediate re-delivery contention.","triggerScenarios":"ValidateConfiguration() runs on AdoNetStreamOptions with VisibilityTimeout < TimeSpan.Zero. The default is 1 minute, so this only fires if it was explicitly set negative.","commonSituations":"Setting VisibilityTimeout = TimeSpan.FromMinutes(-1) by mistake; a config parser producing a negative TimeSpan from a malformed string; unit confusion (ticks vs. seconds).","solutions":["Set options.VisibilityTimeout to a positive TimeSpan (e.g. the default 1 minute).","Validate the config string format (e.g. \"00:01:00\") in appsettings.json.","Use TimeSpan.FromSeconds/FromMinutes to avoid tick/millisecond confusion."],"exampleFix":"// before\nbuilder.AddAdoNetStreams(\"ads\", o =>\n{\n    o.VisibilityTimeout = TimeSpan.FromMinutes(-1);\n});\n\n// after\nbuilder.AddAdoNetStreams(\"ads\", o =>\n{\n    o.VisibilityTimeout = TimeSpan.FromMinutes(2);\n});","handlingStrategy":"validation","validationCode":"static void CheckVisibilityTimeout(AdoNetStreamOptions o)\n{\n    if (o.VisibilityTimeout < TimeSpan.Zero)\n        throw new InvalidOperationException(\"AdoNetStreamOptions.VisibilityTimeout must be non-negative.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use TimeSpan.FromMinutes/FromSeconds with a positive value.","Validate duration config strings with TimeSpan.Parse in a config test.","Avoid computing TimeSpans from raw ticks to prevent sign errors."],"tags":["configuration","adonet","streaming","timeout","startup-validation"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}