{"record":{"id":"edaee5467b48a9be","repo":"JuliusBrussee/caveman","slug":"cachebench-no-providers","errorCode":null,"errorMessage":"cachebench: no providers","messagePattern":"cachebench: no providers","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cacheengine/cachebench/corpus.go","lineNumber":448,"sourceCode":"\tfor _, row := range rows {\n\t\t_ = encoder.Encode(row)\n\t}\n\treturn hex.EncodeToString(hash.Sum(nil))\n}\n\n// RunCorpus evaluates one validated public corpus across provider compilers.\nfunc RunCorpus(ctx context.Context, engine *cacheengine.Engine, corpus AgentCorpus, providers []ProviderConfig, target Target) (Report, error) {\n\tif engine == nil {\n\t\treturn Report{}, errors.New(\"cachebench: nil cache engine\")\n\t}\n\tif err := validateTarget(target); err != nil {\n\t\treturn Report{}, err\n\t}\n\tif len(corpus.Rows) == 0 || corpus.SHA256 == \"\" || strings.TrimSpace(corpus.Metadata.Name) == \"\" {\n\t\treturn Report{}, errors.New(\"cachebench: invalid corpus\")\n\t}\n\tif len(providers) == 0 {\n\t\treturn Report{}, errors.New(\"cachebench: no providers\")\n\t}\n\tif len(providers) > 1024 {\n\t\treturn Report{}, errors.New(\"cachebench: provider population exceeds 1024\")\n\t}\n\tcounter := tokens.Default()\n\tcachedCounter := &corpusTokenCounter{Counter: counter, counts: map[[sha256.Size]byte]int{}}\n\tsummary, err := analyzeCorpus(corpus, cachedCounter)\n\tif err != nil {\n\t\treturn Report{}, err\n\t}\n\tscenario := Scenario{Name: \"public-agent-corpus\", Turns: len(corpus.Rows), Step: time.Second, AssumedTTL: 5 * time.Minute}\n\treport := baseReport(BasisCorpusSimulated, scenario, target, QualityEquivalence)\n\treport.Corpus = &summary\n\treport.Scenario.TokenBasis = counter.Name() + \" estimate over normalized OpenAI messages\"\n\treport.Scenario.Step = \"corpus pre_gap\"\n\treport.Scenario.AssumedTTL = \"provider profile TTL\"\n\tfor _, provider := range providers {\n\t\ttrace, buildErr := buildCorpusTrace(provider, corpus, cachedCounter)","sourceCodeStart":430,"sourceCodeEnd":466,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/cacheengine/cachebench/corpus.go#L430-L466","documentation":"RunCorpus evaluates a corpus across provider compilers, so at least one ProviderConfig is required. An empty providers slice has no meaningful benchmark result and the function rejects it up front.","triggerScenarios":"Calling RunCorpus with a zero-length providers slice — often because provider configs were filtered out (unsupported names, empty API config) before the call, or the config list came from an empty env/section.","commonSituations":"Config file's providers section missing or commented out; providers filtered by a validation pass that rejected all entries; CI running the benchmark with a stripped-down config.","solutions":["Supply at least one ProviderConfig (name + model) to benchmark against","Check earlier filtering/validation code that may have removed every provider and log why each was dropped","Fail fast at config load when the providers list is empty, before entering the benchmark path"],"exampleFix":"// before\nreport, err := cachebench.RunCorpus(ctx, engine, corpus, nil, target)\n\n// after\nif len(providers) == 0 {\n    return fmt.Errorf(\"no providers configured for corpus benchmark\")\n}\nreport, err := cachebench.RunCorpus(ctx, engine, corpus, providers, target)","handlingStrategy":"validation","validationCode":"if len(providers) == 0 {\n    return fmt.Errorf(\"benchmark config error: no providers; add at least one entry to the providers list\")\n}\nreport, err := cachebench.RunCorpus(ctx, engine, corpus, providers, target)","typeGuard":"func hasProviders(ps []ProviderConfig) bool { return len(ps) > 0 }","tryCatchPattern":"if _, err := cachebench.RunCorpus(ctx, engine, corpus, providers, target); err != nil {\n    if err.Error() == \"cachebench: no providers\" {\n        // load/fix provider config and retry once\n    }\n}","preventionTips":["Validate the providers section at config load and fail with the config path in the message","Log which providers were dropped by filtering so an empty list is explainable","Default to at least one well-known provider in test configs"],"tags":["go","corpus","configuration","validation"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}