{"record":{"id":"b801b05e94cad879","repo":"golang-migrate/migrate","slug":"x-no-tx-wrap-s","errorCode":null,"errorMessage":"x-no-tx-wrap: %s","messagePattern":"x-no-tx-wrap: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"database/sqlcipher/sqlcipher.go","lineNumber":112,"sourceCode":"\t}\n\tdbfile := strings.Replace(migrate.FilterCustomQuery(purl).String(), \"sqlite3://\", \"\", 1)\n\tdb, err := sql.Open(\"sqlite3\", dbfile)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tqv := purl.Query()\n\n\tmigrationsTable := qv.Get(\"x-migrations-table\")\n\tif len(migrationsTable) == 0 {\n\t\tmigrationsTable = DefaultMigrationsTable\n\t}\n\n\tnoTxWrap := false\n\tif v := qv.Get(\"x-no-tx-wrap\"); v != \"\" {\n\t\tnoTxWrap, err = strconv.ParseBool(v)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"x-no-tx-wrap: %s\", err)\n\t\t}\n\t}\n\n\tmx, err := WithInstance(db, &Config{\n\t\tDatabaseName:    purl.Path,\n\t\tMigrationsTable: migrationsTable,\n\t\tNoTxWrap:        noTxWrap,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn mx, nil\n}\n\nfunc (m *Sqlite) Close() error {\n\treturn m.db.Close()\n}\n","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/golang-migrate/migrate/blob/01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a/database/sqlcipher/sqlcipher.go#L94-L130","documentation":"The sqlcipher driver's Open parses the x-no-tx-wrap URL query parameter as a boolean (strconv.ParseBool) to decide whether each migration should run outside a transaction. If the value is present but not a valid boolean (\"1\", \"t\", \"true\", \"0\", \"f\", \"false\"), Open returns fmt.Errorf(\"x-no-tx-wrap: %s\", err). The error message embeds the underlying parse error and the offending value.","triggerScenarios":"Opening with a URL like sqlcipher://db.sqlite?x-no-tx-wrap=yes (or \"on\", \"TRUE \", any value strconv.ParseBool rejects) — the parameter is present and non-empty but not a Go-recognized bool string.","commonSituations":"Users writing human-style booleans (\"yes\", \"on\", \"y\") in the DSN; copy-pasting flags from other tools that accept different boolean syntax; trailing whitespace or shell quoting artifacts in the connection string from env vars.","solutions":["Change the query parameter value to a strconv.ParseBool-accepted string: 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False.","Remove the x-no-tx-wrap parameter entirely if you want the default (transaction-wrapped) behavior.","Trim whitespace and shell quotes from the connection string before passing it to migrate.Open/sql.Open."],"exampleFix":"// before\ndsn := \"sqlcipher://data/app.db?x-no-tx-wrap=yes\" // parse error\n// after\ndsn := \"sqlcipher://data/app.db?x-no-tx-wrap=true\"","handlingStrategy":"validation","validationCode":"if v := q.Get(\"x-no-tx-wrap\"); v != \"\" {\n    if _, err := strconv.ParseBool(v); err != nil {\n        return fmt.Errorf(\"invalid x-no-tx-wrap %q: use 1/t/true or 0/f/false\", v)\n    }\n}","typeGuard":"func validBoolParam(v string) bool {\n    _, err := strconv.ParseBool(v)\n    return err == nil\n}","tryCatchPattern":"d, err := sqlcipher.Open(dsn)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"x-no-tx-wrap:\") {\n        return fmt.Errorf(\"fix DSN boolean param (allowed: 1,t,true,0,f,false): %w\", err)\n    }\n    return err\n}","preventionTips":["Only use Go-parseable booleans (1/t/true/0/f/false) in x-no-tx-wrap.","Validate the DSN with url.ParseQuery before passing to Open.","Trim whitespace/quotes from DSNs sourced from env vars or templates.","Omit the parameter entirely when the default (tx-wrapped) behavior is wanted."],"tags":["sqlcipher","sqlite","url-parsing","query-parameter","go"],"backgroundTag":"invalid-boolean-parameter","analyzedSha":"01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a","analyzedAt":"2026-09-02T19:38:29.671Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}