{"record":{"id":"12abe6dd682f422b","repo":"JuliusBrussee/caveman","slug":"s-s-s-capabilities-verified-at-must-be-rfc3339","errorCode":null,"errorMessage":"%s %s/%s: capabilities_verified_at must be RFC3339","messagePattern":"(.+?) (.+?)/(.+?): capabilities_verified_at must be RFC3339","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/catalog/catalog.go","lineNumber":282,"sourceCode":"\t\t\treturn nil, fmt.Errorf(\"%s: provider, model, and region are required\", label)\n\t\t}\n\t\tif entry.Currency != \"USD\" {\n\t\t\treturn nil, fmt.Errorf(\"%s %s/%s: unsupported currency %q\", label, entry.Provider, entry.Model, entry.Currency)\n\t\t}\n\t\tif !cost.ValidPrice(entry.Pricing) {\n\t\t\treturn nil, fmt.Errorf(\"%s %s/%s: invalid pricing\", label, entry.Provider, entry.Model)\n\t\t}\n\t\tverified, err := time.Parse(time.RFC3339, entry.VerifiedAt)\n\t\tif err != nil || verified.IsZero() {\n\t\t\treturn nil, fmt.Errorf(\"%s %s/%s: verified_at must be RFC3339\", label, entry.Provider, entry.Model)\n\t\t}\n\t\tif verified.After(time.Now().UTC().Add(24 * time.Hour)) {\n\t\t\treturn nil, fmt.Errorf(\"%s %s/%s: verified_at is in the future\", label, entry.Provider, entry.Model)\n\t\t}\n\t\tif entry.CapabilitiesVerifiedAt != \"\" {\n\t\t\tcapVerified, err := time.Parse(time.RFC3339, entry.CapabilitiesVerifiedAt)\n\t\t\tif err != nil || capVerified.IsZero() {\n\t\t\t\treturn nil, fmt.Errorf(\"%s %s/%s: capabilities_verified_at must be RFC3339\", label, entry.Provider, entry.Model)\n\t\t\t}\n\t\t\tif capVerified.After(time.Now().UTC().Add(24 * time.Hour)) {\n\t\t\t\treturn nil, fmt.Errorf(\"%s %s/%s: capabilities_verified_at is in the future\", label, entry.Provider, entry.Model)\n\t\t\t}\n\t\t}\n\t\tif len(entry.Sources) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"%s %s/%s: at least one source is required\", label, entry.Provider, entry.Model)\n\t\t}\n\t\tfor _, rawURL := range entry.Sources {\n\t\t\tu, err := url.ParseRequestURI(rawURL)\n\t\t\tif err != nil || u.Scheme != \"https\" || u.Host == \"\" {\n\t\t\t\treturn nil, fmt.Errorf(\"%s %s/%s: invalid HTTPS source %q\", label, entry.Provider, entry.Model, rawURL)\n\t\t\t}\n\t\t}\n\t\tkey := entry.Provider + \"\\x00\" + entry.Model + \"\\x00\" + entry.Region\n\t\tif _, duplicate := seen[key]; duplicate {\n\t\t\treturn nil, fmt.Errorf(\"duplicate provider/model/region row %s/%s@%s\", entry.Provider, entry.Model, entry.Region)\n\t\t}","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/shared/platform/catalog/catalog.go#L264-L300","documentation":"Thrown by the catalog YAML loader when the optional capabilities_verified_at field is present but is neither a valid RFC3339 timestamp nor a non-zero time. It mirrors the verified_at format rule: if you record when capabilities were checked, it must be machine-parseable.","triggerScenarios":"capabilities_verified_at set to \"2026-01-05\" (no time/timezone), \"never\", or any unparseable string; an empty string does NOT trigger this (empty means 'not set' and is allowed).","commonSituations":"Adding the field with a date-only value copied from notes; a schema change where the field became structured but old data kept free-text; hand-editing without noticing the format requirement.","solutions":["Use a full RFC3339 value with timezone: capabilities_verified_at: \"2026-01-05T10:00:00Z\".","If capabilities were never verified, remove the field entirely (empty string or absence skips the check only when the field is absent/empty as documented).","Prefer copying the format from verified_at in the same entry."],"exampleFix":"# before\ncapabilities_verified_at: 2026-01-05\n\n# after\ncapabilities_verified_at: 2026-01-05T10:00:00Z","handlingStrategy":"validation","validationCode":"if entry.CapabilitiesVerifiedAt != \"\" {\n    if t, err := time.Parse(time.RFC3339, entry.CapabilitiesVerifiedAt); err != nil || t.IsZero() {\n        return fmt.Errorf(\"capabilities_verified_at must be RFC3339 or absent\")\n    }\n}","typeGuard":null,"tryCatchPattern":"Fail catalog load at startup; correct or remove the field.","preventionTips":["Omit capabilities_verified_at entirely when capabilities weren't verified.","Use the same RFC3339 generator as verified_at.","Prefer machine-generated catalog edits over manual ones."],"tags":["catalog","yaml","timestamp","rfc3339","validation"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}