{"record":{"id":"b2b98358796325a5","repo":"multica-ai/multica","slug":"check-migration-q-w","errorCode":null,"errorMessage":"check migration %q: %w","messagePattern":"check migration %q: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/migrate/main.go","lineNumber":407,"sourceCode":"\tif _, err := conn.Exec(ctx, fmt.Sprintf(`\n\t\tCREATE TABLE IF NOT EXISTS %s (\n\t\t\tversion TEXT PRIMARY KEY,\n\t\t\tapplied_at TIMESTAMPTZ NOT NULL DEFAULT now()\n\t\t)\n\t`, tableIdent)); err != nil {\n\t\treturn fmt.Errorf(\"create migrations table: %w\", err)\n\t}\n\n\texistsSQL := fmt.Sprintf(\"SELECT EXISTS(SELECT 1 FROM %s WHERE version = $1)\", tableIdent)\n\tinsertSQL := fmt.Sprintf(\"INSERT INTO %s (version) VALUES ($1)\", tableIdent)\n\tdeleteSQL := fmt.Sprintf(\"DELETE FROM %s WHERE version = $1\", tableIdent)\n\n\tfor _, file := range opts.Files {\n\t\tversion := migrations.ExtractVersion(file)\n\n\t\tvar exists bool\n\t\tif err := conn.QueryRow(ctx, existsSQL, version).Scan(&exists); err != nil {\n\t\t\treturn fmt.Errorf(\"check migration %q: %w\", version, err)\n\t\t}\n\n\t\tif opts.Direction == \"up\" {\n\t\t\tif exists {\n\t\t\t\tfmt.Printf(\"  skip  %s (already applied)\\n\", version)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t} else {\n\t\t\tif !exists {\n\t\t\t\tfmt.Printf(\"  skip  %s (not applied)\\n\", version)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tsql, err := os.ReadFile(file)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"read migration %q: %w\", file, err)\n\t\t}","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/migrate/main.go#L389-L425","documentation":"The per-version EXISTS check against schema_migrations failed while scanning. This lookup decides skip-vs-apply for each migration file, so any error aborts the loop before anything is applied for that version. Causes: connection loss, cancelled context, the tracking table being dropped/renamed mid-run by another session, or permissions on it.","triggerScenarios":"Someone drops or truncates schema_migrations while the run is in progress; ctx cancelled; network interruption; SELECT privilege revoked on the tracking table.","commonSituations":"Rare; most often an operator manually messing with schema_migrations during a run, or a flaky connection in long migration sequences.","solutions":["Re-run `migrate up`; applied versions are skipped via the same EXISTS check","Do not manually edit/drop schema_migrations while migrations run — investigate drift with SELECT * FROM schema_migrations ORDER BY version","Grant SELECT on the tracking table to the migration role if permission-denied"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := conn.QueryRow(ctx, existsSQL, version).Scan(&exists); err != nil {\n    return fmt.Errorf(\"check migration %q: %w\", version, err)\n}","preventionTips":["Never manually modify schema_migrations while a run is in progress","Grant the migration role SELECT on the tracking table","Re-run after transient failures — each version re-checks existence"],"tags":["go","postgres","migration","sql","state-table"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}