{"record":{"id":"3c6c68cf25b16a49","repo":"googleapis/mcp-toolbox","slug":"sql-open-w-3c6c68","errorCode":null,"errorMessage":"sql.Open: %w","messagePattern":"sql\\.Open: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/tidb/tidb.go","lineNumber":206,"sourceCode":"\tmatch, err := regexp.MatchString(pattern, host)\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn match\n}\n\nfunc initTiDBConnectionPool(ctx context.Context, tracer trace.Tracer, name, host, port, user, pass, dbname string, useSSL bool) (*sql.DB, error) {\n\t//nolint:all // Reassigned ctx\n\tctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name)\n\tdefer span.End()\n\n\t// Configure the driver to connect to the database\n\tdsn := fmt.Sprintf(\"%s:%s@tcp(%s:%s)/%s?parseTime=true&charset=utf8mb4&tls=%t\", user, pass, host, port, dbname, useSSL)\n\n\t// Interact with the driver directly as you normally would\n\tpool, err := sql.Open(\"mysql\", dsn)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"sql.Open: %w\", err)\n\t}\n\treturn pool, nil\n}\n","sourceCodeStart":188,"sourceCodeEnd":210,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/tidb/tidb.go#L188-L210","documentation":"initTiDBConnectionPool wraps sql.Open failures when constructing the TiDB connection pool. sql.Open only validates the driver name and DSN format — it does not connect — so this almost always indicates a malformed DSN or the mysql driver not being registered. The raw error is preserved with %w.","triggerScenarios":"Config.Initialize -> initTiDBConnectionPool where the composed DSN (user:pass@tcp(host:port)/dbname with parseTime, charset and tls params) is rejected by the mysql driver, e.g. invalid characters in user/password or unparseable DSN fields.","commonSituations":"Password containing special characters (@, :, /) that are not url-escaped before DSN composition; missing or malformed host/port from YAML config; empty dbname producing an invalid DSN.","solutions":["URL-escape credentials with url.UserPassword or url.QueryEscape before building the DSN","Verify TiDB source config fields: host, port (typically 4000), user, password, database are all set and valid","Check the wrapped error for which DSN component the driver rejected","If the driver is unregistered, ensure the mysql driver package is imported"],"exampleFix":"// before\ndsn := fmt.Sprintf(\"%s:%s@tcp(%s:%s)/%s?parseTime=true\", user, pass, host, port, dbname)\n// after\ndsn := fmt.Sprintf(\"%s@tcp(%s:%s)/%s?parseTime=true\", url.UserPassword(user, pass), host, port, dbname)","handlingStrategy":"validation","validationCode":"func validateTiDBConfig(host, port, user, pass, dbname string) error {\n    if host == \"\" || port == \"\" || user == \"\" || dbname == \"\" { return errors.New(\"tidb: host, port, user and database are required\") }\n    if _, err := strconv.Atoi(port); err != nil { return fmt.Errorf(\"tidb: invalid port %q\", port) }\n    if strings.ContainsAny(pass, \"@:/\") && url.QueryEscape(pass) == pass == false { /* escape below */ }\n    _ = url.UserPassword(user, pass) // rejects invalid characters\n    return nil\n}","typeGuard":null,"tryCatchPattern":"pool, err := initTiDBConnectionPool(...)\nif err != nil {\n    return fmt.Errorf(\"sql.Open failed: %w\", err) // inspect wrapped driver message for bad DSN component\n}","preventionTips":["Escape user/password with url.UserPassword before DSN composition","Validate numeric port (default 4000) and non-empty database name at config load time","Smoke-test the DSN with a minimal Go program or mysql CLI before wiring into toolbox","Keep special characters out of credentials or quote/escape them consistently"],"tags":["database","tidb","dsn","connection-pool"],"backgroundTag":"invalid-dsn","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}