{"record":{"id":"dbc9e3975f84b30e","repo":"golang-migrate/migrate","slug":"x-no-tx-wrap-s-dbc9e3","errorCode":null,"errorMessage":"x-no-tx-wrap: %s","messagePattern":"x-no-tx-wrap: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"database/sqlite/sqlite.go","lineNumber":112,"sourceCode":"\t}\n\tdbfile := strings.Replace(migrate.FilterCustomQuery(purl).String(), \"sqlite://\", \"\", 1)\n\tdb, err := sql.Open(\"sqlite\", 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/sqlite/sqlite.go#L94-L130","documentation":"The sqlite driver's Open parses the x-no-tx-wrap URL query parameter as a boolean (strconv.ParseBool) to decide whether migrations run outside a transaction. A present-but-invalid value causes Open to return fmt.Errorf(\"x-no-tx-wrap: %s\", err), embedding the parse error and offending value. Valid values are Go's recognized booleans: 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False.","triggerScenarios":"Opening with a URL like sqlite://app.db?x-no-tx-wrap=on (or \"yes\", \"Y\", \" true\") — the parameter is present and non-empty but strconv.ParseBool rejects it.","commonSituations":"Human-style booleans (\"yes\"/\"on\") in the DSN copied from other tools' docs; shell/env quoting or whitespace contaminating the connection string; templated DSNs where the flag value is substituted from a non-boolean config.","solutions":["Use a strconv.ParseBool-accepted value: true/TRUE/True/t/T/1 or false/FALSE/False/f/F/0.","Omit x-no-tx-wrap entirely to keep the default transaction-wrapped behavior.","Trim whitespace and quotes from the DSN before passing it to migrate.Open/sql.Open."],"exampleFix":"// before\ndsn := \"sqlite://data/app.db?x-no-tx-wrap=on\" // parse error\n// after\ndsn := \"sqlite://data/app.db?x-no-tx-wrap=1\"","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 := sqlite.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":["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"}