{"record":{"id":"cd7cc19e595c1fcc","repo":"Hmbown/CodeWhale","slug":"invalid-host","errorCode":"invalid_host","errorMessage":"ssh computers need a valid host (letters, digits, dot, dash, underscore)","messagePattern":"ssh computers need a valid host \\(letters, digits, dot, dash, underscore\\)","errorType":"validation","errorClass":"RegistryError","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/registry.mjs","lineNumber":88,"sourceCode":"  const c = get(id); // throws unknown_computer\n  const reg = load();\n  reg.active = c.id;\n  save(reg);\n  return c;\n}\n\n/** Register or update a computer. Returns the entry. */\nexport function register({ id, transport, label, ...rest }) {\n  if (!id || !ID_RE.test(id)) throw new RegistryError(\"invalid_id\", \"computer id must match \" + ID_RE);\n  if (![\"local\", \"ssh\", \"hdc\", \"docker\"].includes(transport)) {\n    throw new RegistryError(\"invalid_transport\", \"transport must be one of: local, ssh, hdc, docker\");\n  }\n  if (id === \"local\" && transport !== \"local\") {\n    throw new RegistryError(\"reserved_id\", '\"local\" is reserved for this machine');\n  }\n  if (transport === \"ssh\") {\n    if (!rest.host || !/^[A-Za-z0-9._-]+$/.test(rest.host)) {\n      throw new RegistryError(\"invalid_host\", \"ssh computers need a valid host (letters, digits, dot, dash, underscore)\");\n    }\n    if (rest.port != null && (!Number.isInteger(rest.port) || rest.port < 1 || rest.port > 65535)) {\n      throw new RegistryError(\"invalid_port\", \"port must be an integer in 1..65535\");\n    }\n    if (rest.user != null && !/^[a-zA-Z0-9._-]+$/.test(rest.user)) {\n      throw new RegistryError(\"invalid_user\", \"user must be a plain name\");\n    }\n  }\n  if (transport === \"hdc\") {\n    if (rest.target != null && !/^[A-Za-z0-9._-]*$/.test(rest.target)) {\n      throw new RegistryError(\"invalid_target\", \"hdc target key contains invalid characters\");\n    }\n    rest.platform = \"harmonyos\";\n  }\n  if (transport === \"docker\") {\n    if (!rest.container || !/^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/.test(rest.container)) {\n      throw new RegistryError(\"invalid_container\", \"docker computers need a valid container name\");\n    }","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/registry.mjs#L70-L106","documentation":"RegistryError \"invalid_host\": when transport is \"ssh\", register() requires rest.host to be a non-empty string matching ^[A-Za-z0-9._-]+$ — plain hostnames, IPs in dot notation, and dash/underscore names. The host field is passed to an ssh command line, so anything that would need quoting or parsing (user@host, host:port, IPv6, spaces) is rejected.","triggerScenarios":"register({ id: \"x\", transport: \"ssh\" }) with no host; host: \"user@10.0.0.5\" (put user in rest.user); host: \"[2001:db8::1]\" or \"host:22\"; host containing spaces or a URL scheme.","commonSituations":"Copy-pasting an scp/ssh connection string wholesale into host; omitting host because ssh config on the machine would resolve an alias; IPv6 addresses which the regex does not allow.","solutions":["Set host to the bare hostname or IPv4 address, e.g. host: \"10.0.0.5\".","Move the login name to rest.user and the port to rest.port instead of embedding them in host.","For IPv6 or exotic hostnames, add an /etc/ssh config alias matching [A-Za-z0-9._-]+ and use that alias as host.","Trim whitespace and strip any \"ssh://\" prefix from the host value before registering."],"exampleFix":"// before\nregister({ id: \"lab\", transport: \"ssh\", host: \"alice@10.0.0.5:2222\" });\n// after\nregister({ id: \"lab\", transport: \"ssh\", host: \"10.0.0.5\", user: \"alice\", port: 2222 });","handlingStrategy":"validation","validationCode":"const HOST_RE = /^[A-Za-z0-9._-]+$/;\nif (typeof host !== \"string\" || !HOST_RE.test(host)) throw new Error(\"ssh host must be a bare hostname/IP\");","typeGuard":"const isSshHost = (h) => typeof h === \"string\" && /^[A-Za-z0-9._-]+$/.test(h);","tryCatchPattern":"try {\n  register({ id, transport: \"ssh\", host, user, port });\n} catch (e) {\n  if (e?.code === \"invalid_host\") throw new Error(`Host \"${host}\" rejected; split user@host:port into host/user/port fields`);\n  throw e;\n}","preventionTips":["Never put user@host or host:port in the host field","Strip \"ssh://\" prefixes and whitespace","Use an ssh-config alias for IPv6 or exotic hosts","Validate host against the regex before calling register()"],"tags":["validation","ssh","registry","javascript"],"backgroundTag":"invalid-argument-format","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}