JuliusBrussee/caveman · error
%s %s/%s: invalid pricing
Error message
%s %s/%s: invalid pricing
What it means
Thrown by the catalog YAML loader when an entry's pricing block fails cost.ValidPrice — the structured per-token price fields (input/output/cache etc.) are missing, malformed, or out of range. Validation runs at load so an unusable pricing row never reaches metering.
Source
Thrown at shared/platform/catalog/catalog.go:270
if err == nil {
return nil, fmt.Errorf("multiple YAML documents are not allowed")
}
return nil, err
}
if len(decoded) == 0 {
return nil, fmt.Errorf("catalog is empty")
}
seen := make(map[string]struct{}, len(decoded))
for i, entry := range decoded {
label := fmt.Sprintf("entry %d", i)
if strings.TrimSpace(entry.Provider) == "" || strings.TrimSpace(entry.Model) == "" || strings.TrimSpace(entry.Region) == "" {
return nil, fmt.Errorf("%s: provider, model, and region are required", label)
}
if entry.Currency != "USD" {
return nil, fmt.Errorf("%s %s/%s: unsupported currency %q", label, entry.Provider, entry.Model, entry.Currency)
}
if !cost.ValidPrice(entry.Pricing) {
return nil, fmt.Errorf("%s %s/%s: invalid pricing", label, entry.Provider, entry.Model)
}
verified, err := time.Parse(time.RFC3339, entry.VerifiedAt)
if err != nil || verified.IsZero() {
return nil, fmt.Errorf("%s %s/%s: verified_at must be RFC3339", label, entry.Provider, entry.Model)
}
if verified.After(time.Now().UTC().Add(24 * time.Hour)) {
return nil, fmt.Errorf("%s %s/%s: verified_at is in the future", label, entry.Provider, entry.Model)
}
if entry.CapabilitiesVerifiedAt != "" {
capVerified, err := time.Parse(time.RFC3339, entry.CapabilitiesVerifiedAt)
if err != nil || capVerified.IsZero() {
return nil, fmt.Errorf("%s %s/%s: capabilities_verified_at must be RFC3339", label, entry.Provider, entry.Model)
}
if capVerified.After(time.Now().UTC().Add(24 * time.Hour)) {
return nil, fmt.Errorf("%s %s/%s: capabilities_verified_at is in the future", label, entry.Provider, entry.Model)
}
}
if len(entry.Sources) == 0 {View on GitHub (pinned to 27d5a3981a)
Solutions
- Match the pricing structure of a known-good sibling entry in the same file, with numeric per-token values.
- Run cost.ValidPrice (or the repo's catalog test/lint) on the edited file before shipping to catch the failing row early.
- If prices are genuinely unknown, follow the project's convention for such rows instead of an empty block — check how other unverifiable entries are represented.
Example fix
# before
pricing: {}
# after
pricing:
input_per_mtok: 3.0
output_per_mtok: 15.0 Defensive patterns
Strategy: validation
Validate before calling
if !cost.ValidPrice(entry.Pricing) {
return fmt.Errorf("entry %d %s/%s: pricing block rejected by cost.ValidPrice", i, entry.Provider, entry.Model)
} Try / catch
Fail catalog load at startup with the entry index; do not meter with unvalidated prices.
Prevention
- Copy the pricing block shape from a verified sibling entry.
- Write prices as plain numbers (no currency symbols or thousand separators).
- Run the catalog loader as a lint step in CI.
When it happens
Trigger: Entries with an empty/absent pricing block, non-numeric price strings, negative values, or structurally wrong nesting (e.g. pricing written as a flat scalar instead of the expected shape) — anything cost.ValidPrice rejects.
Common situations: Adding a model with unknown prices and leaving pricing empty; pasting prices with currency symbols or commas ("$3.00", "3,00"); schema drift after the pricing struct gained new required fields.
Related errors
- ${label}: ${key} has no pricing block
- %s: provider, model, and region are required
- %s %s/%s: unsupported currency %q
- ${label}:${lineNo}: "${text}" is not a finite number
- ${label}: row is missing a string "${field}"
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/2b54d31f94774cd7.
Report an issue: GitHub.