{"record":{"id":"dc025db4b8caca07","repo":"ory/kratos","slug":"querying-s","errorCode":null,"errorMessage":"querying %s","messagePattern":"querying (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/migrate/normalize_phone_handler.go","lineNumber":173,"sourceCode":"\t\ttotal.skipped += s.skipped\n\t\ttotal.errors += s.errors\n\t}\n\t_, _ = fmt.Fprintf(tw, \"TOTAL\\t%d\\t%d\\t%d\\t%d\\n\", total.scanned, total.updated, total.skipped, total.errors)\n\t_ = tw.Flush()\n}\n\nfunc normalizeTable(conn *pop.Connection, batchSize int, batchDelay time.Duration, startAfter uuid.UUID, dryRun bool, cmd *cobra.Command, table tableConfig) (normalizeStats, error) {\n\tvar stats normalizeStats\n\tlastID := startAfter\n\n\tfor {\n\t\tvar rows []struct {\n\t\t\tID    uuid.UUID `db:\"id\"`\n\t\t\tValue string    `db:\"value\"`\n\t\t}\n\n\t\tif err := conn.RawQuery(table.selectQuery, lastID, batchSize).All(&rows); err != nil {\n\t\t\treturn stats, errors.Wrapf(err, \"querying %s\", table.name)\n\t\t}\n\n\t\tif len(rows) == 0 {\n\t\t\tbreak\n\t\t}\n\n\t\tfor _, row := range rows {\n\t\t\tlastID = row.ID\n\t\t\tstats.scanned++\n\n\t\t\t// The SQL query pre-filters with LIKE '+%'. This Go-side regex additionally\n\t\t\t// rejects non-phone identifiers (e.g. OIDC subjects) that happen to start\n\t\t\t// with '+'. We cannot use SQL regex because SQLite does not support it.\n\t\t\tif !phonePattern.MatchString(row.Value) {\n\t\t\t\tstats.skipped++\n\t\t\t\tcontinue\n\t\t\t}\n","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/ory/kratos/blob/b86338da04a040247a07f46100a86dcfb3875909/cmd/migrate/normalize_phone_handler.go#L155-L191","documentation":"normalizeTable pages through rows (id, value) of the target table with RawQuery starting after lastID in batches. If the batch SELECT fails, the error is wrapped with \"querying <table>\". It marks the read phase of phone normalization as failed; the wrapped cause names the SQL/connection problem.","triggerScenarios":"Running phone normalization when the batched SELECT (table.selectQuery with lastID and batchSize parameters) fails — connection loss, SQL syntax/dialect mismatch, missing table, or permission denied on select.","commonSituations":"Running the migration against a database user lacking SELECT grants, pointing at a database where the table doesn't exist (wrong schema/database), or transient network drops during long batch runs.","solutions":["Read the wrapped cause for the exact SQL/driver error.","Verify the DB user has SELECT permission on the target table.","Confirm you are connected to the correct database/schema where the table exists.","Re-run with a smaller --batch-size if timeouts occur on large tables; resume via --start-after."],"exampleFix":"// before: wrong database\nexport DSN=postgres://user:pass@localhost:5432/otherdb?sslmode=disable\nkratos migrate normalize-phone\n// after\nexport DSN=postgres://user:pass@localhost:5432/kratos?sslmode=disable\nkratos migrate normalize-phone","handlingStrategy":"retry","validationCode":"// pre-flight: verify table access\n_, err := conn.ExecContext(ctx, \"SELECT 1 FROM identity_credentials LIMIT 1\")\nif err != nil { log.Fatalf(\"cannot read target table: %v\", err) }","typeGuard":"null","tryCatchPattern":"if err := normalizePhoneNumbers(cmd, args); err != nil {\n    if strings.Contains(err.Error(), \"querying \") {\n        // transient DB failure: back off and resume\n        time.Sleep(10 * time.Second)\n        return normalizePhoneNumbers(cmd, args)\n    }\n    return err\n}","preventionTips":["Grant the migration user SELECT on all identity tables","Point the DSN at the correct database/schema","Keep batch sizes modest to avoid long-running queries and timeouts"],"tags":["database","sql","batch-query","migration"],"backgroundTag":"sql-query-failed","analyzedSha":"b86338da04a040247a07f46100a86dcfb3875909","analyzedAt":"2026-09-07T15:58:15.934Z","contentChangedAt":"2026-09-07T15:58:15.934Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}