{"record":{"id":"d90e42d7777945db","repo":"zeroclaw-labs/zeroclaw","slug":"invalid-uno-q-ssh-user-use-only-ascii-letters-di","errorCode":null,"errorMessage":"Invalid Uno Q SSH user: use only ASCII letters, digits, '.', '_', or '-' and do not begin with '-'","messagePattern":"Invalid Uno Q SSH user: use only ASCII letters, digits, '\\.', '_', or '-' and do not begin with '-'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/zeroclaw-hardware/src/peripherals/uno_q_setup.rs","lineNumber":96,"sourceCode":"    println!(\"  transport = \\\"bridge\\\"\");\n    Ok(())\n}\n\nfn validated_ssh_target(value: &str) -> Result<String> {\n    let mut parts = value.split('@');\n    let first = parts.next().unwrap_or_default();\n    let second = parts.next();\n    if parts.next().is_some() {\n        anyhow::bail!(\"Uno Q host must contain at most one '@'\");\n    }\n\n    let (user, host) = match second {\n        Some(host) => (first, host),\n        None => (\"arduino\", first),\n    };\n\n    if !valid_ssh_user(user) {\n        anyhow::bail!(\n            \"Invalid Uno Q SSH user: use only ASCII letters, digits, '.', '_', or '-' and do not begin with '-'\"\n        );\n    }\n    if !valid_ssh_host(host) {\n        anyhow::bail!(\n            \"Invalid Uno Q host: use a DNS hostname or IPv4 address without SSH/SCP syntax characters\"\n        );\n    }\n\n    Ok(format!(\"{user}@{host}\"))\n}\n\nfn valid_ssh_user(user: &str) -> bool {\n    !user.is_empty()\n        && !user.starts_with('-')\n        && user\n            .bytes()\n            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'.' | b'_' | b'-'))","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-hardware/src/peripherals/uno_q_setup.rs#L78-L114","documentation":"After splitting, the SSH user part (explicit, or the 'arduino' default) is checked by valid_ssh_user: non-empty, must not start with '-', and every byte must be an ASCII letter, digit, '.', '_' or '-'. This bail rejects users containing spaces, shell metacharacters, non-ASCII characters, or a leading dash — option-like values that ssh/scp could misparse.","triggerScenarios":"Passing 'user name@host' (space), '-user@host' or '-oProxyCommand=...@host' (leading '-'), 'usér@host' (non-ASCII), or an empty user as in '@host'.","commonSituations":"Pasting usernames with whitespace; trying to pass ssh options through the user field; internationalized system usernames.","solutions":["Use a plain ASCII username: letters, digits, and '.', '_', '-' only, not starting with '-'","Pass ssh options via ~/.ssh/config instead of the host string","For exotic usernames, create an SSH config Host alias with the right User and pass the alias as the host"],"exampleFix":"# before\nsetup_uno_q_bridge(Some(\"my user@uno-q.local\"))\n\n# after\n# ~/.ssh/config:\n#   Host unoq\n#     HostName uno-q.local\n#     User my_user\nsetup_uno_q_bridge(Some(\"unoq\"))","handlingStrategy":"type-guard","validationCode":"let user = host.split('@').next().unwrap_or(\"\");\nif !is_valid_ssh_user(user) {\n    anyhow::bail!(\"invalid SSH user {user:?}: ASCII letters/digits/./_/- only, no leading '-'\");\n}\nsetup_uno_q_bridge(Some(host))?;","typeGuard":"fn is_valid_ssh_user(user: &str) -> bool {\n    !user.is_empty()\n        && !user.starts_with('-')\n        && user.bytes().all(|b| b.is_ascii_alphanumeric() || matches!(b, b'.' | b'_' | b'-'))\n}","tryCatchPattern":null,"preventionTips":["Never pass ssh options through the user/host fields; use ~/.ssh/config","Create SSH Host aliases for unusual usernames","Reject values with spaces or non-ASCII at config-parse time"],"tags":["input-validation","ssh-user","command-injection-guard","uno-q"],"backgroundTag":"invalid-ssh-username","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}