{"record":{"id":"06fd2b9f19171885","repo":"microsoft/FASTER","slug":"size-0-is-not-a-power-of-2","errorCode":null,"errorMessage":"Size {0} is not a power of 2","messagePattern":"Size (.+?) is not a power of 2","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"cs/src/core/Index/FASTER/FASTERBase.cs","lineNumber":400,"sourceCode":"\n        private void Free(int version)\n        {\n#if !NET5_0_OR_GREATER\n            if (state[version].tableHandle.IsAllocated)\n                state[version].tableHandle.Free();\n#endif\n        }\n\n        /// <summary>\n        /// Initialize\n        /// </summary>\n        /// <param name=\"size\"></param>\n        /// <param name=\"sector_size\"></param>\n        public void Initialize(long size, int sector_size)\n        {\n            if (!Utility.IsPowerOfTwo(size))\n            {\n                throw new ArgumentException(\"Size {0} is not a power of 2\");\n            }\n            if (!Utility.Is32Bit(size))\n            {\n                throw new ArgumentException(\"Size {0} is not 32-bit\");\n            }\n\n            minTableSize = size;\n            resizeInfo = default;\n            resizeInfo.status = ResizeOperationStatus.DONE;\n            resizeInfo.version = 0;\n            Initialize(resizeInfo.version, size, sector_size);\n        }\n\n        /// <summary>\n        /// Initialize\n        /// </summary>\n        /// <param name=\"version\"></param>\n        /// <param name=\"size\"></param>","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/microsoft/FASTER/blob/321d872eabda6a0345c8bd76419f89723ed864ae/cs/src/core/Index/FASTER/FASTERBase.cs#L382-L418","documentation":"FASTERBase.Initialize validates that the size parameter (e.g., hash index or overflow-bucket allocation size) is a power of two and fits in 32 bits. The power-of-2 check uses ArgumentException with message 'Size {0} is not a power of 2' when Utility.IsPowerOfTwo(size) is false. The {0} is never substituted, so the raw message appears.","triggerScenarios":"Calling Initialize(size, sector_size) with a size that is not a power of 2, e.g., 1_000_000 instead of 1<<20, or a config-computed size like (long)(n * 1.5).","commonSituations":"User-configured index sizes that ignore the power-of-2 requirement; computing sizes from entry counts without rounding up; porting configs from other systems that allow arbitrary sizes.","solutions":["Round the size up to the next power of 2 before calling Initialize","Use Utility.NextPowerOf2(size) (or equivalent bit trick) to normalize user input","Document/validate the config so only power-of-2 sizes are accepted"],"exampleFix":"// before\nfasterBase.Initialize(1_000_000, sectorSize: 512); // throws\n// after\nlong size = 1_000_000;\nfasterBase.Initialize(Utility.NextPowerOf2(size), sectorSize: 512);","handlingStrategy":"validation","validationCode":"static bool IsPowerOfTwo(long x) => x > 0 && (x & (x - 1)) == 0;\nif (!IsPowerOfTwo(size))\n    size = Utility.NextPowerOf2(size);","typeGuard":null,"tryCatchPattern":"try { fasterBase.Initialize(size, sectorSize); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"not a power of 2\"))\n{\n    fasterBase.Initialize(Utility.NextPowerOf2(size), sectorSize);\n}","preventionTips":["Normalize all user/config sizes with a power-of-2 helper before passing to FASTER","Validate configuration at startup, failing fast with clear messages","Never compute sizes with non-integer arithmetic (e.g., n * 1.5) without rounding to a power of 2"],"tags":["configuration","power-of-two","initialization","faster"],"backgroundTag":"invalid-config-value","analyzedSha":"321d872eabda6a0345c8bd76419f89723ed864ae","analyzedAt":"2026-09-15T22:18:00.693Z","contentChangedAt":"2026-09-15T22:18:00.693Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}