{"record":{"id":"8d92f300d08806c1","repo":"temporalio/temporal","slug":"duplicate-connection-attr-v-v-v-v","errorCode":null,"errorMessage":"duplicate connection attr: %v:%v, %v:%v","messagePattern":"duplicate connection attr: (.+?):(.+?), (.+?):(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/persistence/sql/sqlplugin/sqlite/plugin.go","lineNumber":192,"sourceCode":"\t\t\"file:%s?%v\",\n\t\tcfg.DatabaseName,\n\t\tvals.Encode(),\n\t)\n\treturn dsn, nil\n}\n\nfunc buildDSNAttr(cfg *config.SQL) (url.Values, error) {\n\tparameters := url.Values{}\n\n\t// sort ConnectAttributes to get a deterministic order\n\tkeys := expmaps.Keys(cfg.ConnectAttributes)\n\tsort.Strings(keys)\n\n\tfor _, k := range keys {\n\t\tkey := strings.TrimSpace(k)\n\t\tvalue := strings.TrimSpace(cfg.ConnectAttributes[k])\n\t\tif parameters.Get(key) != \"\" {\n\t\t\treturn nil, fmt.Errorf(\"duplicate connection attr: %v:%v, %v:%v\",\n\t\t\t\tkey,\n\t\t\t\tparameters.Get(key),\n\t\t\t\tkey, value,\n\t\t\t)\n\t\t}\n\n\t\tif _, isValidQueryParameter := queryParameters[key]; isValidQueryParameter {\n\t\t\tparameters.Set(key, value)\n\t\t\tcontinue\n\t\t}\n\n\t\t// assume pragma\n\t\tparameters.Add(\"_pragma\", fmt.Sprintf(\"%s=%s\", key, value))\n\t}\n\t// set time format\n\tparameters.Add(\"_time_format\", \"sqlite\")\n\treturn parameters, nil\n}","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/persistence/sql/sqlplugin/sqlite/plugin.go#L174-L210","documentation":"Returned by buildDSNAttr when a user-supplied ConnectAttributes key duplicates a parameter that is already present in the DSN built from the sqlite config (or another conflicting source). Allowing duplicates would create ambiguous URI query parameters, so the builder rejects it explicitly, listing both conflicting values.","triggerScenarios":"Passing a ConnectAttributes entry whose key collides with parameters already added to the sqlite DSN (e.g. specifying 'mode' or 'cache' in ConnectAttributes when the DSN path/query already encodes it), when calling the sqlite plugin's connection creation path.","commonSituations":"Copy-pasting MySQL/Postgres connect attributes into a sqlite config; explicitly setting _txlock, mode, or cache that the plugin already sets; config templating accidentally inserting the same key twice.","solutions":["Remove the duplicate key from cfg.ConnectAttributes — keep only the plugin-provided value.","If you must override, check buildDSN to see which parameters are pre-populated and choose non-conflicting ones.","Deduplicate keys in your config template/pipeline before it reaches the plugin.","Review the error message: it shows both the existing value and your conflicting value."],"exampleFix":"// before\nconnectAttributes: {\"_txlock\": \"immediate\", \"cache\": \"shared\", \"_txlock\": \"exclusive\"}\n// after\nconnectAttributes: {\"cache\": \"shared\"}","handlingStrategy":"validation","validationCode":"// Go: dedupe and check against plugin-provided params\nreserved := map[string]bool{\"mode\": true, \"cache\": true, \"_txlock\": true}\nfor k := range cfg.ConnectAttributes {\n    if reserved[strings.TrimSpace(k)] {\n        return fmt.Errorf(\"connect attribute %q conflicts with DSN defaults\", k)\n    }\n}","typeGuard":null,"tryCatchPattern":"// Go\nif err != nil && strings.Contains(err.Error(), \"duplicate connection attr\") {\n    return fmt.Errorf(\"remove conflicting sqlite ConnectAttributes: %w\", err)\n}","preventionTips":["Don't set mode/cache/_txlock in ConnectAttributes (plugin provides them)","Deduplicate keys in config templating pipelines","Read buildDSN to learn which parameters are pre-populated","Validate config at startup with a fail-fast check"],"tags":["sqlite","config","dsn","duplicate-attributes"],"backgroundTag":"duplicate-connection-attribute","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}