{"record":{"id":"e1972fe481a1d0ca","repo":"multica-ai/multica","slug":"scan-dry-run-summary-w","errorCode":null,"errorMessage":"scan dry-run summary: %w","messagePattern":"scan dry-run summary: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/backfill_codex_usage_cache/main.go","lineNumber":221,"sourceCode":"\t}\n\tdefer rows.Close()\n\n\tvar summaries []summaryRow\n\tvar total totals\n\tfor rows.Next() {\n\t\tvar row summaryRow\n\t\tif err := rows.Scan(\n\t\t\t&row.WorkspaceID,\n\t\t\t&row.DateUTC,\n\t\t\t&row.Rows,\n\t\t\t&row.InputBefore,\n\t\t\t&row.InputAfter,\n\t\t\t&row.Overcount,\n\t\t\t&row.ClampedRows,\n\t\t\t&row.MinCreatedUTC,\n\t\t\t&row.MaxCreatedUTC,\n\t\t); err != nil {\n\t\t\treturn nil, totals{}, fmt.Errorf(\"scan dry-run summary: %w\", err)\n\t\t}\n\t\tsummaries = append(summaries, row)\n\t\ttotal.Rows += row.Rows\n\t\ttotal.InputBefore += row.InputBefore\n\t\ttotal.InputAfter += row.InputAfter\n\t\ttotal.Overcount += row.Overcount\n\t\ttotal.ClampedRows += row.ClampedRows\n\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn nil, totals{}, fmt.Errorf(\"iterate dry-run summary: %w\", err)\n\t}\n\treturn summaries, total, nil\n}\n\nfunc logSummary(cfg config, rows []summaryRow, total totals) {\n\tslog.Info(\"Codex usage cache backfill candidate total\",\n\t\t\"execute\", cfg.execute,\n\t\t\"cutoff\", cfg.cutoff.Format(time.RFC3339),","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/backfill_codex_usage_cache/main.go#L203-L239","documentation":"Returned when rows.Scan fails while reading one dry-run summary row. The query returns nine columns (workspace_id, date_utc, rows, input_before, input_after, overcount, clamped_rows, min/max created), and a scan mismatch — wrong column count/type expectation or a NULL in a non-nullable scan target — produces this. In practice this indicates the binary and the SQL schema are out of sync, not bad user input.","triggerScenarios":"Running a backfill binary built against a schema where the summary query returns a different column set than the compiled Scan expects; NULLs appearing in columns scanned into non-pointer types.","commonSituations":"Schema drifted after the binary was compiled (a migration added/renamed summary columns); using an old binary against an upgraded database or vice versa.","solutions":["Rebuild/redeploy the backfill binary from the same commit as the database schema (make build within server/).","Run migrations so schema and binary match, then re-run the dry-run.","Inspect the wrapped error — pgx names the offending column/type when it is a conversion failure."],"exampleFix":"# before\n./old-backfill_codex_usage_cache --cutoff ...  # scan dry-run summary: ... (columns moved by migration)\n\n# after\ngit checkout <schema-matching-commit> && make -C server build\n./server/bin/backfill_codex_usage_cache --cutoff 2026-06-01T12:00:00Z","handlingStrategy":"validation","validationCode":"# Ensure binary and schema come from the same commit\ngit -C server log -1 --format=%H > /tmp/backfill.build\ngit checkout $(cat /tmp/backfill.build) && make -C server build","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Deploy the backfill binary built from the same release as the schema migrations.","Never mix an old binary with a migrated database (or vice versa).","Read the wrapped pgx error — it names the exact column/type that failed to scan."],"tags":["database","backfill","schema-drift","scan","build"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}