JuliusBrussee/caveman · error
%s %s/%s: verified_at is in the future
Error message
%s %s/%s: verified_at is in the future
What it means
Thrown by the catalog YAML loader when an entry's verified_at timestamp lies more than 24 hours in the future (UTC). A future-dated verification would misrepresent when prices were checked, so the loader rejects it; the 24h tolerance absorbs reasonable clock skew.
Source
Thrown at shared/platform/catalog/catalog.go:277
}
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 {
return nil, fmt.Errorf("%s %s/%s: at least one source is required", label, entry.Provider, entry.Model)
}
for _, rawURL := range entry.Sources {
u, err := url.ParseRequestURI(rawURL)
if err != nil || u.Scheme != "https" || u.Host == "" {
return nil, fmt.Errorf("%s %s/%s: invalid HTTPS source %q", label, entry.Provider, entry.Model, rawURL)
}View on GitHub (pinned to 27d5a3981a)
Solutions
- Correct the timestamp to the actual verification date (past or within 24h of now).
- Regenerate the field from the machine's real clock at verification time: date -u +%Y-%m-%dT%H:%M:%SZ.
- If it was a build-host clock issue, fix NTP on that host so generated catalogs aren't future-dated.
Example fix
# before verified_at: 2027-08-15T00:00:00Z # after verified_at: 2026-08-14T18:30:00Z
Defensive patterns
Strategy: validation
Validate before calling
func notFutureBeyond24h(s string) bool {
t, err := time.Parse(time.RFC3339, s)
return err == nil && !t.After(time.Now().UTC().Add(24*time.Hour))
} Try / catch
Fail catalog load at startup; fix the date in data. Do not widen the tolerance in code to work around bad data.
Prevention
- Double-check the year when hand-editing dates.
- Keep NTP enabled on hosts and CI runners that generate catalogs.
- Treat future-dated rows as data-entry bugs in review.
When it happens
Trigger: verified_at like "2027-01-01T00:00:00Z" when today is in 2026, or any timestamp more than 24h past time.Now().UTC() — often from a typo in the year, or a machine with a badly wrong clock producing 'now' dates that are ahead for everyone else.
Common situations: Typo'd year (2026 vs 2027); timestamps written on a host whose clock is set months ahead; CI regenerating the catalog with a mocked future time.
Related errors
- %s %s/%s: verified_at must be RFC3339
- %s %s/%s: capabilities_verified_at must be RFC3339
- %s %s/%s: capabilities_verified_at is in the future
- ${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/060408d89585bd72.
Report an issue: GitHub.