{"record":{"id":"933c01631ab2e75d","repo":"multica-ai/multica","slug":"batch-size-must-be-positive","errorCode":null,"errorMessage":"--batch-size must be positive","messagePattern":"--batch-size must be positive","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/backfill_codex_usage_cache/main.go","lineNumber":172,"sourceCode":"\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,\n    MIN(tu.created_at) AS min_created_at,\n    MAX(tu.created_at) AS max_created_at\nFROM task_usage tu","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/backfill_codex_usage_cache/main.go#L154-L190","documentation":"Config validation error: --batch-size was supplied as zero or negative (or its default left uninitialized in a non-flag context). The batch size controls how many task_usage rows each UPDATE round touches, so the tool requires a positive value before proceeding.","triggerScenarios":"Passing --batch-size 0 or a negative number; an wrapper script passing an unset shell variable that expands to nothing/0.","commonSituations":"Parameterized runbooks interpolating an empty variable (--batch-size $BATCH with BATCH unset); attempting 'unbatched' mode with 0; typo'd negative value.","solutions":["Pass a positive integer, e.g. --batch-size 5000.","Default the variable in the script: BATCH=${BATCH:-5000} before invoking.","Tune the value against database load; there is no need for extreme sizes since the tool loops until done."],"exampleFix":"# before\nBATCH=\n./backfill_codex_usage_cache --cutoff ... --batch-size $BATCH\n# --batch-size must be positive\n\n# after\nBATCH=${BATCH:-5000}\n./backfill_codex_usage_cache --cutoff 2026-06-01T12:00:00Z --batch-size $BATCH --execute","handlingStrategy":"validation","validationCode":"BATCH=${BATCH:-5000}\ncase \"$BATCH\" in (*[!0-9]*|'') echo '--batch-size must be a positive integer'; exit 1;; esac\n./backfill_codex_usage_cache --cutoff \"$CUTOFF\" --batch-size \"$BATCH\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default batch variables in runbooks so unset env vars never reach the flag.","Pick moderate sizes (e.g. 1000–10000) — the tool loops to completion on its own."],"tags":["cli","validation","backfill","flags"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}