{"record":{"id":"9c9e17c4daf739b9","repo":"multica-ai/multica","slug":"cutoff-must-be-before-now-refusing-a-future-cut","errorCode":null,"errorMessage":"--cutoff must be before now; refusing a future cutoff because it could double-subtract already-normalized rows","messagePattern":"--cutoff must be before now; refusing a future cutoff because it could double-subtract already-normalized rows","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/backfill_codex_usage_cache/main.go","lineNumber":169,"sourceCode":"\t}\n\tslog.Info(\"hourly rollup rebuilt\",\n\t\t\"from\", rollupFrom.Format(time.RFC3339),\n\t\t\"to\", rollupTo.Format(time.RFC3339),\n\t\t\"rows_touched\", rollupRows)\n\treturn nil\n}\n\nfunc (cfg *config) parseAndValidate(now time.Time) error {\n\tif cfg.cutoffRaw == \"\" {\n\t\treturn fmt.Errorf(\"--cutoff is required; use the hosted deployment time of the Codex usage normalization fix\")\n\t}\n\tcutoff, err := time.Parse(time.RFC3339, cfg.cutoffRaw)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parse --cutoff as RFC3339: %w\", err)\n\t}\n\tcutoff = cutoff.UTC()\n\tif !cutoff.Before(now) {\n\t\treturn fmt.Errorf(\"--cutoff must be before now; refusing a future cutoff because it could double-subtract already-normalized rows\")\n\t}\n\tif cfg.batchSize <= 0 {\n\t\treturn fmt.Errorf(\"--batch-size must be positive\")\n\t}\n\tcfg.cutoff = cutoff\n\treturn nil\n}\n\nfunc loadDryRunSummary(ctx context.Context, pool *pgxpool.Pool, cfg config) ([]summaryRow, totals, error) {\n\tconst query = `\nSELECT\n    a.workspace_id::text AS workspace_id,\n    (tu.created_at AT TIME ZONE 'UTC')::date::text AS date_utc,\n    COUNT(*)::bigint AS rows,\n    COALESCE(SUM(tu.input_tokens), 0)::bigint AS input_before,\n    COALESCE(SUM(GREATEST(tu.input_tokens - tu.cache_read_tokens, 0)), 0)::bigint AS input_after,\n    COALESCE(SUM(tu.input_tokens - GREATEST(tu.input_tokens - tu.cache_read_tokens, 0)), 0)::bigint AS overcount,\n    COUNT(*) FILTER (WHERE tu.input_tokens < tu.cache_read_tokens)::bigint AS clamped_rows,","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/backfill_codex_usage_cache/main.go#L151-L187","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\n./backfill_codex_usage_cache --cutoff 2027-01-01T00:00:00Z  # wrong year → future\n# --cutoff must be before now; ...\n\n# after\n./backfill_codex_usage_cache --cutoff 2026-06-01T12:00:00Z","handlingStrategy":"validation","validationCode":"# Refuse future cutoffs in the wrapper\nnow=$(date -u +%s); c=$(date -u -d \"$CUTOFF\" +%s)\n[ \"$c\" -lt \"$now\" ] || { echo 'cutoff must be in the past'; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the fix's deployment timestamp, never 'now', as the cutoff.","Double-check the year and UTC conversion — the comparison happens after cutoff.UTC()."],"tags":["cli","validation","time","backfill","data-integrity"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}