{"record":{"id":"d55235162fee8b5b","repo":"dotnet/orleans","slug":"invalid-nameof-adonetstreamoptions-values-for-a-d55235","errorCode":null,"errorMessage":"Invalid {nameof(AdoNetStreamOptions)} values for ADO.NET Streaming Provider '{name}': {nameof(options.MaxAttempts)} 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":25,"sourceCode":"/// </summary>\npublic class AdoNetStreamOptionsValidator(AdoNetStreamOptions options, string name) : IConfigurationValidator\n{\n    /// <inheritdoc />\n    public void ValidateConfiguration()\n    {\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)","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/AdoNet/Orleans.Streaming.AdoNet/AdoNetStreamOptionsValidator.cs#L7-L43","documentation":"Thrown by the ADO.NET streaming options validator when MaxAttempts is negative. MaxAttempts bounds how many delivery attempts a message gets before moving to dead letters. Note the check is `< 0`, so zero is technically accepted though the message text says 'greater than zero' — a value of 0 would let messages dead-letter immediately.","triggerScenarios":"ValidateConfiguration() runs on AdoNetStreamOptions with MaxAttempts < 0. The default is 5, so this only fires if MaxAttempts was explicitly set to a negative integer.","commonSituations":"Setting MaxAttempts = -1 intending 'unlimited' (not supported); misreading a config key; binding a missing config key that resolves to -1 via a custom parser.","solutions":["Set options.MaxAttempts to a positive integer (e.g. the default 5).","If you want high resilience, use a large finite number rather than a negative sentinel.","Check the appsettings.json value for typos or a missing-key default of -1."],"exampleFix":"// before\nbuilder.AddAdoNetStreams(\"ads\", o =>\n{\n    o.MaxAttempts = -1; // error\n});\n\n// after\nbuilder.AddAdoNetStreams(\"ads\", o =>\n{\n    o.MaxAttempts = 10;\n});","handlingStrategy":"validation","validationCode":"static void CheckMaxAttempts(AdoNetStreamOptions o)\n{\n    if (o.MaxAttempts < 0)\n        throw new InvalidOperationException(\"AdoNetStreamOptions.MaxAttempts must be non-negative; use a positive finite value.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a positive finite MaxAttempts (default 5).","Never use a negative sentinel to mean 'unlimited'.","Bind config keys with a parser that fails on negatives rather than coercing."],"tags":["configuration","adonet","streaming","delivery","startup-validation"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}