multica-ai/multica · error
--cutoff must be before now; refusing a future cutoff becaus
Error message
--cutoff must be before now; refusing a future cutoff because it could double-subtract already-normalized rows
What it means
Config validation guard: the parsed --cutoff is not strictly before the current time, and the tool refuses future cutoffs. Rationale: rows with updated_at/created_at after the cutoff are assumed already normalized by the fixed code; a future cutoff would make the correction re-subtract cache_read_tokens from rows that were already normalized, double-counting.
Source
Thrown at server/cmd/backfill_codex_usage_cache/main.go:169
}
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,
COALESCE(SUM(tu.input_tokens), 0)::bigint AS input_before,
COALESCE(SUM(GREATEST(tu.input_tokens - tu.cache_read_tokens, 0)), 0)::bigint AS input_after,
COALESCE(SUM(tu.input_tokens - GREATEST(tu.input_tokens - tu.cache_read_tokens, 0)), 0)::bigint AS overcount,
COUNT(*) FILTER (WHERE tu.input_tokens < tu.cache_read_tokens)::bigint AS clamped_rows,View on GitHub (pinned to 2c0912b6ec)
Solutions
- Set --cutoff to the actual hosted deployment time of the Codex usage normalization fix — always in the past.
- If you really meant 'everything', use a safely past timestamp (e.g. the fix deployment moment), not now.
- Double-check the year/timezone in the timestamp; note the value is converted to UTC before comparison.
Example fix
# before ./backfill_codex_usage_cache --cutoff 2027-01-01T00:00:00Z # wrong year → future # --cutoff must be before now; ... # after ./backfill_codex_usage_cache --cutoff 2026-06-01T12:00:00Z
Defensive patterns
Strategy: validation
Validate before calling
# Refuse future cutoffs in the wrapper
now=$(date -u +%s); c=$(date -u -d "$CUTOFF" +%s)
[ "$c" -lt "$now" ] || { echo 'cutoff must be in the past'; exit 1; } Prevention
- Use the fix's deployment timestamp, never 'now', as the cutoff.
- Double-check the year and UTC conversion — the comparison happens after cutoff.UTC().
When it happens
Trigger: Passing a cutoff at or after the current clock time (now), including a cutoff exactly equal to now; also clock skew if the operator's machine is behind the intended cutoff timezone-wise after UTC conversion.
Common situations: Picking 'now' or tomorrow as a backstop; copy-pasting a deployment date from the future by typo (wrong year); generating the cutoff from a script that emits a wrong (future) date.
Related errors
- parse --cutoff as RFC3339: %w
- --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/9c9e17c4daf739b9.
Report an issue: GitHub.