{"record":{"id":"c81a684bae1a2346","repo":"JuliusBrussee/caveman","slug":"cachebench-nil-corpus-reader","errorCode":null,"errorMessage":"cachebench: nil corpus reader","messagePattern":"cachebench: nil corpus reader","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cacheengine/cachebench/corpus.go","lineNumber":137,"sourceCode":"}\n\ntype lmcacheRowWire struct {\n\tSessionID    string          `json:\"session_id\"`\n\tModel        string          `json:\"model\"`\n\tInput        json.RawMessage `json:\"input\"`\n\tOutputLength int             `json:\"output_length\"`\n\tPreGap       float64         `json:\"pre_gap\"`\n}\n\ntype hfRowWire struct {\n\tRowIndex int            `json:\"row_idx\"`\n\tRow      lmcacheRowWire `json:\"row\"`\n}\n\n// ReadAgentCorpus imports supported JSONL formats under explicit limits.\nfunc ReadAgentCorpus(reader io.Reader, format string, metadata CorpusMetadata, limits CorpusLimits) (AgentCorpus, error) {\n\tif reader == nil {\n\t\treturn AgentCorpus{}, errors.New(\"cachebench: nil corpus reader\")\n\t}\n\tif !validBoundedText(metadata.Name, 512, false) || !validBoundedText(metadata.License, 256, true) || !validBoundedText(metadata.Revision, 512, true) {\n\t\treturn AgentCorpus{}, errors.New(\"cachebench: invalid corpus metadata\")\n\t}\n\tvar err error\n\tlimits, err = normalizedCorpusLimits(limits)\n\tif err != nil {\n\t\treturn AgentCorpus{}, err\n\t}\n\tlimited := &io.LimitedReader{R: reader, N: limits.MaxInputBytes + 1}\n\tvar rows []CorpusRow\n\tswitch format {\n\tcase CorpusFormatLMCacheJSONL:\n\t\trows, err = readLMCacheJSONL(limited, limits)\n\tcase CorpusFormatHFRows:\n\t\trows, err = readHFRows(limited, limits)\n\tdefault:\n\t\treturn AgentCorpus{}, fmt.Errorf(\"cachebench: unsupported corpus format %q\", format)","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/cacheengine/cachebench/corpus.go#L119-L155","documentation":"Returned by ReadAgentCorpus() when the io.Reader passed in is nil. The importer is the entry point for converting JSONL corpora into the benchmark's internal representation; a nil reader would panic on the first Read, so it is rejected up front with a namespaced error ('cachebench:') before any metadata validation or format dispatch happens.","triggerScenarios":"Calling ReadAgentCorpus(nil, ...) directly; a loader that returns a nil *os.File (failed os.Open whose error was swallowed) and passes it through; a test constructing the call without opening a fixture file.","commonSituations":"Go's classic os.Open error-shadowing bug (err captured but file still used); optional-input plumbing where a missing path becomes nil; wiring a new corpus source that forgets to open its file.","solutions":["Ensure the reader comes from a successful open: `f, err := os.Open(path); if err != nil { return err }; defer f.Close()` before calling ReadAgentCorpus.","If the input is genuinely optional, skip the call entirely rather than passing nil.","In tests, open the fixture (os.Open(testdata/file.jsonl)) instead of passing a nil literal placeholder."],"exampleFix":"// before\nf, _ := os.Open(path) // error ignored; f may be nil\ncorpus, err := cachebench.ReadAgentCorpus(f, \"hf\", meta, limits)\n\n// after\nf, err := os.Open(path)\nif err != nil { return err }\ndefer f.Close()\ncorpus, err := cachebench.ReadAgentCorpus(f, \"hf\", meta, limits)","handlingStrategy":"validation","validationCode":"// Go: never pass a nil reader\nfunc openCorpus(path string) (io.Reader, error) {\n    f, err := os.Open(path)\n    if err != nil {\n        return nil, err\n    }\n    return f, nil // caller: defer f.Close()\n}","typeGuard":"func nonNilReader(r io.Reader) (io.Reader, bool) {\n    return r, r != nil\n}","tryCatchPattern":null,"preventionTips":["Always check os.Open's error and return it — the classic nil *os.File bug produces exactly this error.","Skip optional corpus imports rather than passing nil readers.","In tests, open real fixture files; never stub the reader with nil."],"tags":["go","validation","nil-check","benchmark","corpus"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}