multica-ai/multica · error
parse --cutoff as RFC3339: %w
Error message
parse --cutoff as RFC3339: %w
What it means
Config validation error: the --cutoff value could not be parsed as RFC3339 (time.Parse(time.RFC3339, ...)). The tool requires a full RFC3339 timestamp with timezone, e.g. 2026-06-01T12:00:00Z; date-only values, missing time, or a missing zone offset all fail here. The wrapped time.Parse error names the exact offending element.
Source
Thrown at server/cmd/backfill_codex_usage_cache/main.go:165
rollupFrom, rollupTo,
).Scan(&rollupRows); err != nil {
return fmt.Errorf("rebuild hourly rollup for update window %s..%s: %w",
rollupFrom.Format(time.RFC3339), rollupTo.Format(time.RFC3339), err)
}
slog.Info("hourly rollup rebuilt",
"from", rollupFrom.Format(time.RFC3339),
"to", rollupTo.Format(time.RFC3339),
"rows_touched", rollupRows)
return nil
}
func (cfg *config) parseAndValidate(now time.Time) error {
if cfg.cutoffRaw == "" {
return fmt.Errorf("--cutoff is required; use the hosted deployment time of the Codex usage normalization fix")
}
cutoff, err := time.Parse(time.RFC3339, cfg.cutoffRaw)
if err != nil {
return fmt.Errorf("parse --cutoff as RFC3339: %w", err)
}
cutoff = cutoff.UTC()
if !cutoff.Before(now) {
return fmt.Errorf("--cutoff must be before now; refusing a future cutoff because it could double-subtract already-normalized rows")
}
if cfg.batchSize <= 0 {
return fmt.Errorf("--batch-size must be positive")
}
cfg.cutoff = cutoff
return nil
}
func loadDryRunSummary(ctx context.Context, pool *pgxpool.Pool, cfg config) ([]summaryRow, totals, error) {
const query = `
SELECT
a.workspace_id::text AS workspace_id,
(tu.created_at AT TIME ZONE 'UTC')::date::text AS date_utc,
COUNT(*)::bigint AS rows,View on GitHub (pinned to 2c0912b6ec)
Solutions
- Format the timestamp as RFC3339 with an explicit zone: --cutoff 2026-06-01T12:00:00Z.
- Generate it programmatically: date -u +%Y-%m-%dT%H:%M:%SZ.
- Read the wrapped error's detail — it states whether the T separator, hours, or timezone offset was missing.
Example fix
# before ./backfill_codex_usage_cache --cutoff 2026-06-01 # parse --cutoff as RFC3339: ... # after ./backfill_codex_usage_cache --cutoff $(date -u -d '2026-06-01 12:00' +%Y-%m-%dT%H:%M:%SZ)
Defensive patterns
Strategy: validation
Validate before calling
# Generate a valid RFC3339 cutoff CUTOFF=$(date -u -d "$DEPLOY_TIME" +%Y-%m-%dT%H:%M:%SZ) || exit 1 ./backfill_codex_usage_cache --cutoff "$CUTOFF"
Prevention
- Always emit cutoffs with date -u +%Y-%m-%dT%H:%M:%SZ rather than hand-writing them.
- Remember RFC3339 requires the T separator and an explicit zone (Z or ±HH:MM).
When it happens
Trigger: Passing --cutoff 2026-06-01 (date only), --cutoff '2026-06-01 12:00:00' (space separator, no zone), or a timestamp without the T separator or timezone designator.
Common situations: Using the output of `date` on some locales verbatim; copying a cutoff from SQL output (often no zone); treating the flag as date-valued because the dry-run summary groups by UTC date.
Related errors
- --cutoff must be before now; refusing a future cutoff becaus
- --cutoff is required; use the hosted deployment time of the
- --batch-size must be positive
- load dry-run summary: %w
- --months-back=%d would skip buckets before %s (oldest availa
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/d08bc286e969bb62.
Report an issue: GitHub.