{"record":{"id":"5e957f4447e8d5cc","repo":"t8y2/dbx","slug":"invalid-tdengine-http-connection-string","errorCode":null,"errorMessage":"invalid TDengine HTTP connection string","messagePattern":"invalid TDengine HTTP connection string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/tdengine/src/config.rs","lineNumber":102,"sourceCode":"    let normalized = if let Some(value) = strip_prefix_ignore_ascii_case(trimmed, \"jdbc:TAOS-WS://\") {\n        format!(\"{}://{value}\", if ssl { \"wss\" } else { \"ws\" })\n    } else if let Some(value) = strip_prefix_ignore_ascii_case(trimmed, \"jdbc:TAOS-RS://\") {\n        format!(\"{}://{value}\", if ssl { \"wss\" } else { \"ws\" })\n    } else if let Some(value) = strip_prefix_ignore_ascii_case(trimmed, \"tdengine://\") {\n        format!(\"{}://{value}\", if ssl { \"wss\" } else { \"ws\" })\n    } else if let Some(value) = strip_prefix_ignore_ascii_case(trimmed, \"taosws://\") {\n        format!(\"{}://{value}\", if ssl { \"wss\" } else { \"ws\" })\n    } else if let Some(value) = strip_prefix_ignore_ascii_case(trimmed, \"taoswss://\") {\n        format!(\"wss://{value}\")\n    } else {\n        trimmed.to_string()\n    };\n    let mut url = Url::parse(&normalized).with_context(|| \"invalid TDengine connection string\")?;\n    if !matches!(url.scheme(), \"ws\" | \"wss\" | \"http\" | \"https\") {\n        bail!(\"TDengine native agent supports only WebSocket connection strings\");\n    }\n    if matches!(url.scheme(), \"http\") {\n        url.set_scheme(\"ws\").map_err(|_| anyhow::anyhow!(\"invalid TDengine HTTP connection string\"))?;\n    } else if matches!(url.scheme(), \"https\") {\n        url.set_scheme(\"wss\").map_err(|_| anyhow::anyhow!(\"invalid TDengine HTTPS connection string\"))?;\n    }\n    remove_control_params(&mut url);\n    Ok(url)\n}\n\nfn merge_query_params(url: &mut Url, raw: &str) {\n    let raw = raw.trim().trim_start_matches('?');\n    if raw.is_empty() {\n        return;\n    }\n    let additions = url::form_urlencoded::parse(raw.as_bytes())\n        .filter(|(key, _)| !is_control_param(key))\n        .map(|(key, value)| (key.into_owned(), value.into_owned()))\n        .collect::<Vec<_>>();\n    let mut query = url.query_pairs_mut();\n    for (key, value) in additions {","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/tdengine/src/config.rs#L84-L120","documentation":"normalize_connection_string parses a user-supplied TDengine connection string and, for http:// URLs, rewrites the scheme to ws:// with Url::set_scheme. set_scheme fails when the new scheme is invalid in context — here because an http URL with a default port or unusual port/scheme state cannot be renamed — so the driver raises 'invalid TDengine HTTP connection string'. This means an http:// DSN could not be converted to its WebSocket equivalent.","triggerScenarios":"Passing an http:// connection string to build_dsn where Url::set_scheme(\"ws\") fails, notably when the URL has no explicit port (set_scheme rejects changing scheme when it would invalidate the default port binding).","commonSituations":"Users writing 'http://host:6041' or a URL relying on http's default port 80 and expecting transparent WebSocket upgrade; copy-pasted REST-interface URLs from TDengine docs (taosAdapter REST on 6041).","solutions":["Change the connection string scheme from http:// to ws:// yourself before passing it in.","Include an explicit port in the URL (e.g. ws://host:6041/) so scheme rewriting is unambiguous.","Use wss:// instead of https:// if TLS is needed."],"exampleFix":"// before\nlet dsn = build_dsn(Some(\"http://localhost:6041\"), &params)?;\n// after\nlet dsn = build_dsn(Some(\"ws://localhost:6041\"), &params)?;","handlingStrategy":"validation","validationCode":"// Rust\nlet url = url::Url::parse(conn_str)?;\nif url.scheme() == \"http\" {\n    return Err(\"rewrite http:// to ws:// with an explicit port before passing to build_dsn\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always author TDengine DSNs with ws:// or wss:// schemes up front.","Include an explicit port (default 6041) in every connection string.","Do not reuse REST-interface http(s) URLs for the WebSocket agent."],"tags":["tdengine","websocket","url-parsing"],"backgroundTag":"invalid-connection-string","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}