JuliusBrussee/caveman · error
row limit %d exceeded
Error message
row limit %d exceeded
What it means
appendCorpusRow refuses to add another row because the number of accumulated rows has already reached limits.MaxRows. This is a hard cap that keeps the in-memory corpus bounded; the check fires before the row is appended, so the corpus stays at exactly MaxRows.
Source
Thrown at cacheengine/cachebench/corpus.go:390
}
for _, call := range message.ToolCalls {
if call.Type != "function" || !validBoundedText(call.ID, 2048, false) || !validBoundedText(call.Function.Name, 512, false) || !validUniqueJSONObject([]byte(call.Function.Arguments)) {
return errors.New("tool call requires function type, id, function name, and JSON arguments")
}
messageBytes += len(call.ID) + len(call.Type) + len(call.Function.Name) + len(call.Function.Arguments)
}
if messageBytes > limits.MaxMessageBytes {
return errors.New("message exceeds byte limit")
}
if message.Role == "tool" && message.ToolCallID == "" {
return errors.New("tool message requires tool_call_id")
}
return nil
}
func appendCorpusRow(rows *[]CorpusRow, sessions map[string]bool, retainedBytes *int64, row CorpusRow, limits CorpusLimits) error {
if len(*rows) >= limits.MaxRows {
return fmt.Errorf("row limit %d exceeded", limits.MaxRows)
}
if !sessions[row.SessionID] {
if len(sessions) >= limits.MaxSessions {
return fmt.Errorf("session limit %d exceeded", limits.MaxSessions)
}
sessions[row.SessionID] = true
}
rowBytes := corpusRowRetainedBytes(row)
if rowBytes > limits.MaxRetainedBytes-*retainedBytes {
return fmt.Errorf("retained corpus byte limit %d exceeded", limits.MaxRetainedBytes)
}
*retainedBytes += rowBytes
*rows = append(*rows, row)
return nil
}
func corpusRetainedBytes(rows []CorpusRow) int64 {
var total int64View on GitHub (pinned to 27d5a3981a)
Solutions
- Raise CorpusLimits.MaxRows to cover the corpus size (count lines in the JSONL first).
- Split the corpus file into shards each within MaxRows and load them separately.
- Subsample the corpus to fit the current cap using the tool's own sampling/export options.
Example fix
// before limits.MaxRows = 10_000 // after limits.MaxRows = 100_000
Defensive patterns
Strategy: validation
Validate before calling
func countCorpusRows(path string) (int, error) {
f, err := os.Open(path)
if err != nil {
return 0, err
}
defer f.Close()
n := 0
scanner := bufio.NewScanner(f)
for scanner.Scan() {
if len(bytes.TrimSpace(scanner.Bytes())) > 0 {
n++
}
}
return n, scanner.Err()
}
// before loading:
// n, _ := countCorpusRows(path); if n > limits.MaxRows { limits.MaxRows = n } Prevention
- Count corpus lines and compare against MaxRows before loading.
- Derive limits from corpus metadata instead of hard-coding them.
- Shard large corpora rather than loosening caps ad hoc.
When it happens
Trigger: Loading a corpus whose row count exceeds CorpusLimits.MaxRows: on the (MaxRows+1)-th call to appendCorpusRow, len(*rows) >= MaxRows and the error is returned.
Common situations: Pointing the loader at a larger capture file than the configured budget allows, or reusing tight default limits with a production-sized trace.
Related errors
- cachebench: provider population exceeds 1024
- cachebench: no providers
- cachebench: invalid observation read limits
- cacheengine: stable prefix exceeds configured byte limit
- cacheengine: request exceeds configured byte limit
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/f02483212d66ce72.
Report an issue: GitHub.