JuliusBrussee/caveman · error
cachebench: verifier returned incomplete or mismatched evide
Error message
cachebench: verifier returned incomplete or mismatched evidence
What it means
The final gate in ParseVerificationCommandOutput: no trailing JSON after the object, schema equal to VerificationSchema, request_id equal to the expected one, verifier a bounded non-empty text (<=256), and evidence present, valid JSON, and not null. Any mismatch means the evidence cannot be attributed to this request and is rejected.
Source
Thrown at cacheengine/cachebench/replay.go:62
Verifier string `json:"verifier"`
Evidence json.RawMessage `json:"evidence"`
}
// ParseVerificationCommandOutput validates and binds external grader evidence.
func ParseVerificationCommandOutput(raw []byte, requestID string) (TaskVerification, error) {
raw = bytes.TrimSpace(raw)
if !validUniqueJSONObject(raw) {
return TaskVerification{}, errors.New("cachebench: verifier returned duplicate or invalid JSON")
}
decoder := json.NewDecoder(bytes.NewReader(raw))
decoder.DisallowUnknownFields()
var result VerificationCommandOutput
if decoder.Decode(&result) != nil {
return TaskVerification{}, errors.New("cachebench: verifier returned invalid JSON")
}
var trailing any
if decoder.Decode(&trailing) != io.EOF || result.Schema != VerificationSchema || result.RequestID != requestID || !validBoundedText(result.Verifier, 256, false) || len(result.Evidence) == 0 || !json.Valid(result.Evidence) || bytes.Equal(bytes.TrimSpace(result.Evidence), []byte("null")) {
return TaskVerification{}, errors.New("cachebench: verifier returned incomplete or mismatched evidence")
}
return TaskVerification{Passed: result.Passed, Verifier: result.Verifier, Evidence: append([]byte(nil), raw...)}, nil
}
// ReplayLimits bounds paid population, schedule, and concurrency.
type ReplayLimits struct {
MaxRequests int
MaxDeclaredBilledTokens int64
MaxGap time.Duration
MaxScheduleDrift time.Duration
MaxConcurrency int
RequireGroundedTiming bool
RequireProviderTokens bool
}
// ReplayPreflight is zero-network validation and declared-budget summary.
type ReplayPreflight struct {
Requests int `json:"requests"`View on GitHub (pinned to 27d5a3981a)
Solutions
- Pass the exact request_id being verified and have the grader echo it unchanged
- Ensure evidence is always a non-null JSON value (empty object {} is acceptable, null is not)
- Keep schema pinned to VerificationSchema and update both sides together on version bumps
- Run graders one-at-a-time per request or prefix outputs per goroutine to avoid interleaving
Example fix
// before
v, err := ParseVerificationCommandOutput(raw, otherRequestID) // mismatch
// grader emitted "evidence": null
// after
v, err := ParseVerificationCommandOutput(raw, req.ID)
// grader emits "evidence": {} minimum Defensive patterns
Strategy: validation
Validate before calling
if v.RequestID != requestID || v.Schema != expectedSchema || len(bytes.TrimSpace(v.Evidence)) == 0 || bytes.Equal(bytes.TrimSpace(v.Evidence), []byte("null")) {
return errors.New("evidence not attributable to this request")
}
verification, err := cachebench.ParseVerificationCommandOutput(raw, requestID) Type guard
func evidenceAttributable(raw []byte, requestID, schema string) bool {
var v struct {
Schema string `json:"schema"`; RequestID string `json:"request_id"`
Verifier string `json:"verifier"`; Evidence json.RawMessage `json:"evidence"`
}
if json.Unmarshal(raw, &v) != nil { return false }
return v.Schema == schema && v.RequestID == requestID && v.Verifier != "" && len(v.Verifier) <= 256 &&
len(v.Evidence) > 0 && !bytes.Equal(bytes.TrimSpace(v.Evidence), []byte("null"))
} Try / catch
if _, err := cachebench.ParseVerificationCommandOutput(raw, req.ID); err != nil {
if err.Error() == "cachebench: verifier returned incomplete or mismatched evidence" {
// verify request_id plumbing and evidence non-null before rerunning the grader
}
} Prevention
- Echo the request_id argument verbatim in grader output; assert equality on both sides
- Never emit null evidence — use {} for empty
- Upgrade grader and cachebench schema versions together
- Serialize concurrent grader output per request to prevent cross-attribution
When it happens
Trigger: request_id in the grader output differing from the request being verified; missing/empty evidence or literal null evidence; schema field not matching the expected VerificationSchema constant; verifier name blank or over 256 chars; concatenated trailing JSON.
Common situations: Grader runs concurrently and outputs interleaved by request, so IDs cross; passing the wrong request_id argument when parsing; grader emitting "evidence": null on skip paths; schema version mismatch after an upgrade.
Related errors
- cachebench: verifier returned duplicate or invalid JSON
- cachebench: verifier returned invalid JSON
- cachebench: no replay evidence
- cachebench: replay token summary overflow
- cache-replay: verifier process failed
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/67a5d62304dd2101.
Report an issue: GitHub.