{"record":{"id":"77b174a8fbde9b02","repo":"golang-migrate/migrate","slug":"x-migrations-table-must-be-quoted-for-instance","errorCode":null,"errorMessage":"x-migrations-table must be quoted (for instance '\"migrate\".\"schema_migrations\"') when x-migrations-table-quoted is enabled, current value is: %s","messagePattern":"x-migrations-table must be quoted \\(for instance '\"migrate\"\\.\"schema_migrations\"'\\) when x-migrations-table-quoted is enabled, current value is: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"database/pgx/pgx.go","lineNumber":188,"sourceCode":"\t// when making actual connection\n\t// i.e. pgx://user:password@host:port/db => postgres://user:password@host:port/db\n\tpurl.Scheme = \"postgres\"\n\n\tdb, err := sql.Open(\"pgx/v4\", migrate.FilterCustomQuery(purl).String())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tmigrationsTable := purl.Query().Get(\"x-migrations-table\")\n\tmigrationsTableQuoted := false\n\tif s := purl.Query().Get(\"x-migrations-table-quoted\"); len(s) > 0 {\n\t\tmigrationsTableQuoted, err = strconv.ParseBool(s)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to parse option x-migrations-table-quoted: %w\", err)\n\t\t}\n\t}\n\tif (len(migrationsTable) > 0) && (migrationsTableQuoted) && ((migrationsTable[0] != '\"') || (migrationsTable[len(migrationsTable)-1] != '\"')) {\n\t\treturn nil, fmt.Errorf(\"x-migrations-table must be quoted (for instance '\\\"migrate\\\".\\\"schema_migrations\\\"') when x-migrations-table-quoted is enabled, current value is: %s\", migrationsTable)\n\t}\n\n\tstatementTimeoutString := purl.Query().Get(\"x-statement-timeout\")\n\tstatementTimeout := 0\n\tif statementTimeoutString != \"\" {\n\t\tstatementTimeout, err = strconv.Atoi(statementTimeoutString)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tmultiStatementMaxSize := DefaultMultiStatementMaxSize\n\tif s := purl.Query().Get(\"x-multi-statement-max-size\"); len(s) > 0 {\n\t\tmultiStatementMaxSize, err = strconv.Atoi(s)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif multiStatementMaxSize <= 0 {","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/golang-migrate/migrate/blob/01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a/database/pgx/pgx.go#L170-L206","documentation":"When `x-migrations-table-quoted=true` is set in the pgx DSN, the `x-migrations-table` value is used verbatim as a quoted SQL identifier, so it must start and end with a double quote (e.g. \"migrate\".\"schema_migrations\"). The library throws this error when quoting is enabled but the table name is not fully double-quoted, to prevent generating invalid SQL or silently using the wrong identifier.","triggerScenarios":"A DSN like `postgres://...?x-migrations-table=migrate.schema_migrations&x-migrations-table-quoted=true` — the table value lacks surrounding double quotes, so Open returns this error before opening any migration session.","commonSituations":"Developers enabling the quoted option for a case-sensitive or schema-qualified migrations table but forgetting to add the quotes inside the URL value (remember the quotes must be URL-encoded as %22 in most cases); copying the non-quoted form from other driver docs; shell quoting stripping the literal double quotes.","solutions":["Wrap the table name (and optional schema) in double quotes: x-migrations-table=\"migrate\".\"schema_migrations\", URL-encoding quotes as %22 where needed.","If you don't need a quoted identifier, set x-migrations-table-quoted=false or remove it and pass the plain table name.","Verify the value after shell/env expansion — bash and YAML often strip inner double quotes; escape or single-quote appropriately.","Confirm the first and last characters of the final string are both double quotes (the check is on the first and last byte)."],"exampleFix":"// before\ndsn := \"postgres://user:pass@host/db?x-migrations-table=migrate.schema_migrations&x-migrations-table-quoted=true\"\n// after\ndsn := \"postgres://user:pass@host/db?x-migrations-table=%22migrate%22.%22schema_migrations%22&x-migrations-table-quoted=true\"","handlingStrategy":"validation","validationCode":"u, _ := url.Parse(dsn)\ntbl := u.Query().Get(\"x-migrations-table\")\nquoted := u.Query().Get(\"x-migrations-table-quoted\") == \"true\"\nif quoted && tbl != \"\" && (tbl[0] != '\"' || tbl[len(tbl)-1] != '\"') {\n    return fmt.Errorf(\"x-migrations-table %q must be double-quoted when x-migrations-table-quoted=true\", tbl)\n}","typeGuard":null,"tryCatchPattern":"if err := m.Up(); err != nil {\n    if strings.Contains(err.Error(), \"must be quoted\") {\n        return fmt.Errorf(\"set x-migrations-table=\\\"schema\\\".\\\"table\\\" (URL-encode quotes as %%22): %w\", err)\n    }\n}","preventionTips":["URL-encode double quotes as %22 when embedding quoted identifiers in a DSN","Only enable x-migrations-table-quoted when you actually need a case-sensitive/qualified table","Watch for shells and YAML stripping literal double quotes from the value"],"tags":["postgresql","config","sql-quoting","migrations"],"backgroundTag":"migrations-table-not-quoted","analyzedSha":"01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a","analyzedAt":"2026-09-02T19:38:29.671Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}