{"record":{"id":"c59643c77d754309","repo":"JuliusBrussee/caveman","slug":"ccr-storage-budget-d-is-below-minimum-d","errorCode":null,"errorMessage":"ccr storage budget %d is below minimum %d","messagePattern":"ccr storage budget (.+?) is below minimum (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/ccr/store_sqlite.go","lineNumber":170,"sourceCode":"// never evicted because an emitted transformed request may still reference any\n// handle.\nfunc OpenWithBudget(path string, maxBytes int64) (*Store, error) {\n\treturn openWithBudget(path, maxBytes, nil)\n}\n\nfunc openWithBudget(path string, maxBytes int64, afterPrepare func()) (*Store, error) {\n\treturn openWithBudgetHooks(path, maxBytes, afterPrepare, nil)\n}\n\nfunc openWithBudgetHooks(path string, maxBytes int64, afterPrepare, afterOpen func()) (*Store, error) {\n\tif maxBytes <= 0 {\n\t\treturn nil, fmt.Errorf(\"ccr max storage bytes must be positive\")\n\t}\n\t// SQLite pages are at least 512 bytes. Reject budgets that cannot satisfy\n\t// CCR's minimum page count before preparing files or opening a connection.\n\t// The actual database page size is checked by configureStorageBudget.\n\tif maxBytes < minimumStoragePages*512 {\n\t\treturn nil, fmt.Errorf(\"ccr storage budget %d is below minimum %d\", maxBytes, minimumStoragePages*512)\n\t}\n\tcanonicalPath, err := PrepareSQLitePathCanonical(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif afterPrepare != nil {\n\t\tafterPrepare()\n\t}\n\tbefore, err := inspectSQLiteGeneration(canonicalPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdsn := SQLiteDSN(canonicalPath)\n\tif canonicalPath != \":memory:\" {\n\t\t// PrepareSQLitePathCanonical already created the file. Never recreate\n\t\t// it if it vanishes between preparation and the driver's open.\n\t\tdsn += \"&mode=rw\"\n\t}","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/engine/ccr/store_sqlite.go#L152-L188","documentation":"SQLite pages are at least 512 bytes, and CCR requires a minimum page count (minimumStoragePages). openWithBudgetHooks rejects budgets below minimumStoragePages*512 before preparing files or opening a connection, because such a budget can never satisfy the minimum page requirement. The actual (possibly larger) page size is verified later by configureStorageBudget.","triggerScenarios":"OpenWithBudget is called with maxBytes in (0, minimumStoragePages*512) — e.g. budgets like 1024 or 4096 bytes that are positive but too small for the required number of minimum-size SQLite pages.","commonSituations":"A developer picks a tiny budget for unit tests ('1KB should be enough'); a config typo like 500 instead of 500000; a size unit misread as KB instead of bytes (5 * 1024 for '5KB' intended as 5MB); a proportional budget computed from a small quota.","solutions":["Raise the budget to at least minimumStoragePages*512 bytes; in practice use a realistic value such as several megabytes (e.g. 16*1024*1024).","Read the minimum from the package if exported, or size the budget at the default (use ccr.Open) for tests.","Check the unit: if your config is in KB/MB, multiply to bytes before calling OpenWithBudget.","If the budget is proportional to a quota, clamp it with Math.Max against the library minimum before opening.","For genuinely constrained environments, use :memory: (no budget floor needed) rather than a too-small disk budget."],"exampleFix":"// before\nccr.OpenWithBudget(path, 1024) // below minimum pages\n// after\nccr.OpenWithBudget(path, 16*1024*1024)","handlingStrategy":"validation","validationCode":"if maxBytes < 4096 { // conservative floor; use exported minimum when available\n    return fmt.Errorf(\"budget %d below sqlite minimum pages\", maxBytes)\n}\nccr.OpenWithBudget(path, maxBytes)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use realistic multi-megabyte budgets even in tests","Watch for KB/MB-to-bytes unit conversion mistakes in config","Clamp computed/proportional budgets to the library minimum","Prefer ccr.Open (default budget) or :memory: for constrained cases"],"tags":["go","sqlite","config","budget","value-out-of-range"],"backgroundTag":"value-out-of-range","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}