{"record":{"id":"2f711672780d677a","repo":"dotnet/machinelearning","slug":"cache-size-must-be-a-positive-number","errorCode":null,"errorMessage":"Cache size must be a positive number.","messagePattern":"Cache size must be a positive number\\.","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.ML.Tokenizers/Utils/LruCache.cs","lineNumber":33,"sourceCode":"        public const int DefaultCacheSize = 8192;\n\n        private readonly Dictionary<StringSpanOrdinalKey, LinkedListNode<KeyValuePair<string, TValue>>> _cache = new();\n        private readonly LinkedList<KeyValuePair<string, TValue>> _lruList = new();\n        private readonly int _cacheSize;\n\n        private object SyncObj => _cache;\n\n        /// <summary>\n        /// Constructs an <see cref=\"LruCache{TValue}\" /> object.\n        /// </summary>\n        /// <param name=\"cacheSize\">\n        /// The maximum number of mappings that can be cached. This defaults to <see cref=\"DefaultCacheSize\" />, which is set to <value>8192</value>.\n        /// </param>\n        public LruCache(int cacheSize = DefaultCacheSize)\n        {\n            if (cacheSize <= 0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(cacheSize), \"Cache size must be a positive number.\");\n            }\n\n            _cacheSize = cacheSize;\n        }\n\n        /// <summary>\n        /// Retrieves the value associated with the specified key /> object.\n        /// </summary>\n        /// <param name=\"key\">The object to be used as a key.</param>\n        /// <param name=\"value\">An out parameter that is set to the value of the key if key contains a mapping in the cache.</param>\n        /// <returns>\n        /// true if the cache contains a mapping for key, false otherwise.\n        /// </returns>\n        public bool TryGetValue(string key, out TValue value)\n        {\n            lock (SyncObj)\n            {\n                if (_cache.TryGetValue(new StringSpanOrdinalKey(key), out LinkedListNode<KeyValuePair<string, TValue>>? cached))","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/dotnet/machinelearning/blob/7b76e69cf964daeca3f1377af6bc5543284d56c6/src/Microsoft.ML.Tokenizers/Utils/LruCache.cs#L15-L51","documentation":"The LruCache constructor validates cacheSize and throws ArgumentOutOfRangeException when it is zero or negative, since the cache must be able to hold at least one entry. This is an eager constructor guard so bad configuration fails at construction time rather than at first use.","triggerScenarios":"Constructing LruCache<TValue>(cacheSize) with cacheSize <= 0 — typically from a config value read as 0 when a setting is missing/unparsed, or code doing maxEntries - something that underflows to a negative number.","commonSituations":"An app setting like CacheSize read from an empty/invalid config value defaulting to 0, an int.Parse of a non-numeric string coerced to 0, or arithmetic producing negative capacity.","solutions":["Pass a positive cache size, e.g. Math.Max(1, configuredSize) or the DefaultCacheSize (8192).","Fix config parsing so a missing CacheSize value falls back to DefaultCacheSize instead of 0.","Validate configuration values at startup, before constructing the cache.","Guard: if (size <= 0) size = LruCache.DefaultCacheSize; at the call site."],"exampleFix":"// before\nint size = int.TryParse(config[\"CacheSize\"], out var s) ? s : 0;\nvar cache = new LruCache<string>(size);\n// after\nint size = int.TryParse(config[\"CacheSize\"], out var s) && s > 0 ? s : LruCache<int>.DefaultCacheSize;\nvar cache = new LruCache<string>(size);","handlingStrategy":"validation","validationCode":"if (cacheSize <= 0) cacheSize = LruCache<string>.DefaultCacheSize;\nvar cache = new LruCache<string>(cacheSize);","typeGuard":"static bool IsValidCacheSize(int size) => size > 0;","tryCatchPattern":"try { cache = new LruCache<string>(configuredSize); }\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"cacheSize\")\n{ cache = new LruCache<string>(); } // fall back to default","preventionTips":["Default missing config values to DefaultCacheSize, not 0","Validate cache configuration at startup","Use Math.Max(1, value) on any computed capacity"],"tags":["cache","argument-out-of-range","configuration","lru"],"backgroundTag":"argument-out-of-range","analyzedSha":"7b76e69cf964daeca3f1377af6bc5543284d56c6","analyzedAt":"2026-09-11T12:35:38.930Z","contentChangedAt":"2026-09-11T12:35:38.930Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}