{"record":{"id":"66e7d2a6d605b648","repo":"t8y2/dbx","slug":"invalid-tdengine-password","errorCode":null,"errorMessage":"invalid TDengine password","messagePattern":"invalid TDengine password","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/tdengine/src/config.rs","lineNumber":60,"sourceCode":"        .map(|segment| percent_decode_str(segment).decode_utf8_lossy().into_owned())\n        .unwrap_or_default();\n    Ok(BuiltDsn { value: url.into(), database })\n}\n\nfn build_from_fields(params: &ConnectParams) -> Result<Url> {\n    let scheme = if params.ssl { \"wss\" } else { \"ws\" };\n    let host = if params.host.trim().is_empty() { DEFAULT_HOST } else { params.host.trim() };\n    let port = if params.port == 0 { DEFAULT_PORT } else { params.port };\n    let username = if params.username.is_empty() { DEFAULT_USER } else { &params.username };\n    let password = if params.password.is_empty() { DEFAULT_PASSWORD } else { &params.password };\n    let mut url = Url::parse(&format!(\"{scheme}://{DEFAULT_HOST}:{port}/\"))?;\n    if let Ok(address) = host.parse::<IpAddr>() {\n        url.set_ip_host(address).map_err(|_| anyhow::anyhow!(\"invalid TDengine host\"))?;\n    } else {\n        url.set_host(Some(host)).map_err(|_| anyhow::anyhow!(\"invalid TDengine host\"))?;\n    }\n    url.set_username(username).map_err(|_| anyhow::anyhow!(\"invalid TDengine username\"))?;\n    url.set_password(Some(password)).map_err(|_| anyhow::anyhow!(\"invalid TDengine password\"))?;\n    if !params.database.trim().is_empty() {\n        url.set_path(&format!(\"/{}\", params.database.trim()));\n    }\n    Ok(url)\n}\n\nfn apply_connection_fields(url: &mut Url, params: &ConnectParams) -> Result<()> {\n    if url.username().is_empty() {\n        let username = if params.username.is_empty() { DEFAULT_USER } else { &params.username };\n        url.set_username(username).map_err(|_| anyhow::anyhow!(\"invalid TDengine username\"))?;\n    }\n    if url.password().is_none() {\n        let password = if params.password.is_empty() { DEFAULT_PASSWORD } else { &params.password };\n        url.set_password(Some(password)).map_err(|_| anyhow::anyhow!(\"invalid TDengine password\"))?;\n    }\n    if url.path().trim_matches('/').is_empty() && !params.database.trim().is_empty() {\n        url.set_path(&format!(\"/{}\", params.database.trim()));\n    }","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/tdengine/src/config.rs#L42-L78","documentation":"In build_from_fields, the password is set with Url::set_password after the username. A failure there is surfaced as 'invalid TDengine password'. set_password fails only when the resulting URL is structurally invalid (e.g. a ':' inside the password, which breaks userinfo parsing), since most characters are percent-encoded automatically.","triggerScenarios":"Calling build_dsn with a ConnectParams.password containing characters that cannot form valid userinfo — chiefly an embedded ':' or control characters.","commonSituations":"Passwords copied from documentation that include a separator character, secrets manager values with embedded newlines, or password/username fields swapped so a username with ':' lands in the password slot.","solutions":["Remove any ':' or control characters from the password, or ensure the value is a valid single secret string.","Verify username and password fields are not swapped in the config.","Trim whitespace/newlines from the password before constructing ConnectParams."],"exampleFix":"// before\npassword: \"taos:data\".into() // embedded ':' breaks userinfo\n// after\npassword: \"taosdata\".into()","handlingStrategy":"validation","validationCode":"// Rust\nfn is_valid_password(p: &str) -> bool {\n    !p.contains(':') && p.chars().all(|c| !c.is_control())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid ':' in passwords, or URL-encode credentials by placing them in the DSN userinfo.","Verify username/password fields are not swapped in config.","Trim secrets fetched from secret managers to strip trailing newlines."],"tags":["tdengine","url-parsing","credentials"],"backgroundTag":"invalid-url-credentials","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"}