{"record":{"id":"fbfc25039ef04164","repo":"hatoo/oha","slug":"parse-auth","errorCode":null,"errorMessage":"Parse auth","messagePattern":"Parse auth","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/main.rs","lineNumber":518,"sourceCode":"\n        if let Some(h) = opts.accept_header {\n            headers.insert(http::header::ACCEPT, HeaderValue::from_bytes(h.as_bytes())?);\n        }\n\n        if let Some(h) = opts.content_type.or(form_content_type) {\n            headers.insert(\n                http::header::CONTENT_TYPE,\n                HeaderValue::from_bytes(h.as_bytes())?,\n            );\n        }\n\n        if let Some(h) = opts.host {\n            headers.insert(http::header::HOST, HeaderValue::from_bytes(h.as_bytes())?);\n        }\n\n        if let Some(auth) = opts.basic_auth {\n            let u_p = auth.splitn(2, ':').collect::<Vec<_>>();\n            anyhow::ensure!(u_p.len() == 2, anyhow::anyhow!(\"Parse auth\"));\n            let mut header_value = b\"Basic \".to_vec();\n            {\n                use std::io::Write;\n                let username = u_p[0];\n                let password = if u_p[1].is_empty() {\n                    None\n                } else {\n                    Some(u_p[1])\n                };\n                let mut encoder = base64::write::EncoderWriter::new(\n                    &mut header_value,\n                    &base64::engine::general_purpose::STANDARD,\n                );\n                // The unwraps here are fine because Vec::write* is infallible.\n                write!(encoder, \"{username}:\").unwrap();\n                if let Some(password) = password {\n                    write!(encoder, \"{password}\").unwrap();\n                }","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/hatoo/oha/blob/4efba2d113d165aaaf7533f5d2893e7cc57ebfc1/src/main.rs#L500-L536","documentation":"When building the basic-auth header from --auth, run() splits the string with splitn(2, ':') and requires exactly two segments (username and password). An --auth value without any colon fails this ensure with the terse 'Parse auth' error while constructing request headers.","triggerScenarios":"Passing `--auth` (or `--basic-auth`) a string containing no ':' when not using --aws-sigv4, e.g. `--auth alice` or an empty/whitespace value.","commonSituations":"Providing only the username and forgetting the password; accidentally quoting away the colon; confusing --auth semantics with other tools that take just a token.","solutions":["Provide --auth as `username:password`, always including the colon.","For an empty password use a trailing colon, e.g. `--auth alice:` (the code accepts empty passwords).","Check shell quoting so the full colon-containing string reaches oha."],"exampleFix":"// before\noha --auth alice https://example.com\n// after\noha --auth alice:s3cret https://example.com","handlingStrategy":"validation","validationCode":"fn valid_basic_auth(auth: &str) -> bool {\n    auth.contains(':')\n}","typeGuard":"fn split_basic_auth(auth: &str) -> Option<(&str, &str)> {\n    auth.split_once(':')\n}","tryCatchPattern":"match run(opts).await {\n    Err(e) if e.to_string().contains(\"Parse auth\") => {\n        eprintln!(\"--auth must be username:password (colon required)\");\n    }\n    Err(e) => return Err(e),\n    Ok(v) => v,\n}","preventionTips":["Always include the colon even when the password is empty (e.g. `user:`).","Quote the --auth value so the shell does not split it.","Distinguish --auth basic-auth usage from the AWS credentials usage when --aws-sigv4 is set."],"tags":["cli","basic-auth","credentials","parsing"],"backgroundTag":"invalid-argument-format","analyzedSha":"4efba2d113d165aaaf7533f5d2893e7cc57ebfc1","analyzedAt":"2026-09-09T16:24:23.306Z","contentChangedAt":"2026-09-09T16:24:23.306Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}