zeroclaw-labs/zeroclaw · warning

Invalid Uno Q host: use a DNS hostname or IPv4 address witho

Error message

Invalid Uno Q host: use a DNS hostname or IPv4 address without SSH/SCP syntax characters

What it means

The host part is checked by valid_ssh_host: non-empty, and every dot-separated label must start and end with an alphanumeric and contain only alphanumerics or '-' — i.e. a DNS hostname or IPv4 address. The message calls out the key exclusion: no SSH/SCP syntax characters. Colons (ports, IPv6), slashes (remote paths), brackets, '%', leftover '@', and empty labels ('host..example') all fail.

Source

Thrown at crates/zeroclaw-hardware/src/peripherals/uno_q_setup.rs:101

    let mut parts = value.split('@');
    let first = parts.next().unwrap_or_default();
    let second = parts.next();
    if parts.next().is_some() {
        anyhow::bail!("Uno Q host must contain at most one '@'");
    }

    let (user, host) = match second {
        Some(host) => (first, host),
        None => ("arduino", first),
    };

    if !valid_ssh_user(user) {
        anyhow::bail!(
            "Invalid Uno Q SSH user: use only ASCII letters, digits, '.', '_', or '-' and do not begin with '-'"
        );
    }
    if !valid_ssh_host(host) {
        anyhow::bail!(
            "Invalid Uno Q host: use a DNS hostname or IPv4 address without SSH/SCP syntax characters"
        );
    }

    Ok(format!("{user}@{host}"))
}

fn valid_ssh_user(user: &str) -> bool {
    !user.is_empty()
        && !user.starts_with('-')
        && user
            .bytes()
            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'.' | b'_' | b'-'))
}

fn valid_ssh_host(host: &str) -> bool {
    !host.is_empty()
        && host.split('.').all(|label| {

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Pass only a bare hostname or IPv4: 'uno-q.local', '192.168.0.48'
  2. Drop port and path syntax — configure ports in ~/.ssh/config (Host alias plus Port) instead
  3. IPv6 addresses are unsupported by this validator; use an SSH config alias with HostName set to the IPv6 address

Example fix

# before
setup_uno_q_bridge(Some("arduino@192.168.0.48:22"))

# after
setup_uno_q_bridge(Some("arduino@192.168.0.48"))
Defensive patterns

Strategy: type-guard

Validate before calling

let host_part = host.rsplit('@').next().unwrap_or("");
if !is_valid_ssh_host(host_part) {
    anyhow::bail!("invalid host {host_part:?}: bare DNS name or IPv4 only (no ports/paths/IPv6)");
}
setup_uno_q_bridge(Some(host))?;

Type guard

fn is_valid_ssh_host(host: &str) -> bool {
    !host.is_empty()
        && host.split('.').all(|label| {
            !label.is_empty()
                && label.as_bytes().first().is_some_and(u8::is_ascii_alphanumeric)
                && label.as_bytes().last().is_some_and(u8::is_ascii_alphanumeric)
                && label.bytes().all(|b| b.is_ascii_alphanumeric() || b == b'-')
        })
}

Prevention

When it happens

Trigger: Passing 'host:22' (port), 'user@host:/path' (scp destination), 'ssh://host', '[::1]' or 'fe80::1%eth0' (IPv6/zones), 'host..example' (empty label), or '-host' (label starts with a dash).

Common situations: Pasting scp-style targets or URLs; IPv6 link-local addresses; muscle memory from tools that accept host:port syntax.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/977a77cd2cec2a26. Report an issue: GitHub.