JuliusBrussee/caveman · error

%s: provider, model, and region are required

Error message

%s: provider, model, and region are required

What it means

Thrown by the pricing catalog YAML loader when an entry has an empty (or whitespace-only) provider, model, or region field after trimming. Every catalog row must be fully identified so pricing lookups key on provider+model+region; a row missing any part is rejected at load time.

Source

Thrown at shared/platform/catalog/catalog.go:264

	var decoded []Entry
	if err := dec.Decode(&decoded); err != nil {
		return nil, err
	}
	var trailing any
	if err := dec.Decode(&trailing); err != io.EOF {
		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)

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Open the catalog YAML at the entry index in the error message and fill in provider, model, and region (all non-empty after trimming).
  2. For providers without a meaningful region, use the project's conventional region value used by sibling entries rather than leaving it blank.
  3. If generated, fix the generator to require all three fields per row and re-run.

Example fix

# before
- provider: anthropic
  model: claude-sonnet-4
  region: ""

# after
- provider: anthropic
  model: claude-sonnet-4
  region: us
Defensive patterns

Strategy: validation

Validate before calling

func validCatalogEntry(e Entry) bool {
    return strings.TrimSpace(e.Provider) != "" &&
        strings.TrimSpace(e.Model) != "" &&
        strings.TrimSpace(e.Region) != ""
}

Try / catch

Catch catalog load errors at startup and fail fast with the file path + entry index; do not run with a partial catalog.

Prevention

When it happens

Trigger: A catalog YAML entry like {provider: "", model: "claude-...", region: "us-east-1"}, or one where region is absent entirely (YAML omits missing keys as empty strings). The error names the offending entry by its 0-based index ('entry N').

Common situations: Hand-editing the catalog YAML and dropping a field; a generator script emitting rows with missing region for providers that have none (e.g. forgetting a default like 'us' or 'global'); copy-paste of a row that deletes the region line.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/dcb7f549a73d9f6b. Report an issue: GitHub.