JuliusBrussee/caveman · error
budget is below CCR storage minimum
Error message
budget %d is below CCR storage minimum %d
What it means
configureStorageBudget enforces a CCR storage budget via SQLite PRAGMA max_page_count. This error is returned when the requested budget in bytes, divided by the database page size, yields fewer pages than minimumStoragePages (16), meaning the configured maxBytes is too small to be usable for the store.
Solutions
- Increase the configured storage budget to at least 16 pages (check PRAGMA page_size of the db; commonly >= 65536 bytes)
- Check the config/env value supplying maxBytes for unit mistakes (KB vs bytes)
- Let the library choose a default budget instead of passing an explicit tiny one
- Verify the actual minimum via the error message: minimumStoragePages*pageSize
Example fix
// before store, err := ccr.Open(dbPath, ccr.WithMaxStorageBytes(1024)) // below minimum // after store, err := ccr.Open(dbPath, ccr.WithMaxStorageBytes(1<<20)) // 1 MiB
Defensive patterns
Strategy: validation
Validate before calling
const minBytes = 16 * 4096 // minimumStoragePages * page_size
func budgetOK(maxBytes int64) bool { return maxBytes >= minBytes } Try / catch
if err := configureBudget(db, maxBytes); err != nil && strings.Contains(err.Error(), "below CCR storage minimum") {
return fmt.Errorf("raise maxBytes to at least 16 pages: %w", err)
} Prevention
- Clamp configured budgets to a sane minimum (e.g. 1 MiB) before passing to Open
- Watch for KB/MB vs bytes unit mistakes in config
- Compute budgets from measured record sizes, not guesses
When it happens
Trigger: Calling Open/openWithBudgetHooks with a very small maxBytes (less than 16 * page_size, typically 16*4096 = 64KB); a config file supplying e.g. maxStorageBytes: 1024; a miscomputed budget from environment variables or a downsized deployment config.
Common situations: Operator typo setting the budget in KB while the code expects bytes; aggressive disk-quota configuration for small containers; unit mismatch after migrating config from another tool.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- cave_ccr_budget_exceeded
- ccr storage budget is below minimum
- aes cipher
- cave_subagent_wallet_denomination_unavailable
- ccr max storage bytes must be positive
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/3355f5709bb400ba.
Report an issue: GitHub.
Appendix: source
Thrown at engine/ccr/store_sqlite.go:386
return err
}
if !os.SameFile(info, secured) {
return fmt.Errorf("file changed while securing")
}
return nil
}
func configureStorageBudget(db *sql.DB, maxBytes int64) error {
var pageSize int64
if err := db.QueryRow(`PRAGMA page_size`).Scan(&pageSize); err != nil {
return fmt.Errorf("read page size: %w", err)
}
if pageSize <= 0 {
return errors.New("invalid sqlite page size")
}
maxPages := maxBytes / pageSize
if maxPages < minimumStoragePages {
return fmt.Errorf("budget %d is below CCR storage minimum %d", maxBytes, minimumStoragePages*pageSize)
}
var applied int64
if err := db.QueryRow(fmt.Sprintf(`PRAGMA max_page_count=%d`, maxPages)).Scan(&applied); err != nil {
return err
}
if applied < maxPages {
maxPages = applied
}
autoCheckpoint := maxPages / 16
if autoCheckpoint < 1 {
autoCheckpoint = 1
}
if _, err := db.Exec(fmt.Sprintf(`PRAGMA wal_autocheckpoint=%d`, autoCheckpoint)); err != nil {
return err
}
_, err := db.Exec(fmt.Sprintf(`PRAGMA journal_size_limit=%d`, maxBytes/8))
return err
}View on GitHub (pinned to 3ee70a1026)