Hmbown/CodeWhale · error · RegistryError
invalid_port
invalid_port
Error message
port must be an integer in 1..65535
What it means
RegistryError "invalid_port": for ssh transports, an optional rest.port must be an integer between 1 and 65535. Strings, floats, 0, negatives, and values above 65535 are all rejected because the value ends up as a numeric ssh -p argument.
Solutions
- Convert to an integer first: port: Number.parseInt(raw, 10), and only pass it when the result is a valid integer.
- Use a value in 1..65535; the default ssh port 22 can simply be omitted.
- Fix config sources that emit strings (YAML unquoted numbers, env vars) at parse time.
- Validate with Number.isInteger(p) && p >= 1 && p <= 65535 before calling register().
Example fix
// before
register({ id: "lab", transport: "ssh", host: "10.0.0.5", port: process.env.SSH_PORT });
// after
const p = Number.parseInt(process.env.SSH_PORT, 10);
register({ id: "lab", transport: "ssh", host: "10.0.0.5", ...(Number.isInteger(p) ? { port: p } : {}) }); Defensive patterns
Strategy: validation
Validate before calling
const p = Number.parseInt(rawPort, 10);
const validPort = Number.isInteger(p) && p >= 1 && p <= 65535;
if (rawPort != null && !validPort) throw new Error("port must be an integer in 1..65535"); Type guard
const isValidPort = (p) => Number.isInteger(p) && p >= 1 && p <= 65535;
Try / catch
try {
register(cfg);
} catch (e) {
if (e?.code === "invalid_port") console.error(`Port ${JSON.stringify(cfg.port)} is not a valid 1..65535 integer`);
throw e;
} Prevention
- Convert env/YAML string ports with Number.parseInt at parse time
- Omit port for the default 22
- Reject NaN early — parseInt of empty input yields NaN
- Check Number.isInteger, not typeof number, since floats pass typeof
When it happens
Trigger: register({ id: "x", transport: "ssh", host: "h", port: "2222" }) (string from config/CLI); port: 0 or port: 70000; port: 22.5; port from Number.parseInt of user input that was empty (NaN).
Common situations: YAML/JSON config that reads ports as strings; environment-variable-supplied ports never converted to Number; computing a port from a formula that yields NaN or a float.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/148d51f98a9da11f.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/src/registry.mjs:91
save(reg);
return c;
}
/** Register or update a computer. Returns the entry. */
export function register({ id, transport, label, ...rest }) {
if (!id || !ID_RE.test(id)) throw new RegistryError("invalid_id", "computer id must match " + ID_RE);
if (!["local", "ssh", "hdc", "docker"].includes(transport)) {
throw new RegistryError("invalid_transport", "transport must be one of: local, ssh, hdc, docker");
}
if (id === "local" && transport !== "local") {
throw new RegistryError("reserved_id", '"local" is reserved for this machine');
}
if (transport === "ssh") {
if (!rest.host || !/^[A-Za-z0-9._-]+$/.test(rest.host)) {
throw new RegistryError("invalid_host", "ssh computers need a valid host (letters, digits, dot, dash, underscore)");
}
if (rest.port != null && (!Number.isInteger(rest.port) || rest.port < 1 || rest.port > 65535)) {
throw new RegistryError("invalid_port", "port must be an integer in 1..65535");
}
if (rest.user != null && !/^[a-zA-Z0-9._-]+$/.test(rest.user)) {
throw new RegistryError("invalid_user", "user must be a plain name");
}
}
if (transport === "hdc") {
if (rest.target != null && !/^[A-Za-z0-9._-]*$/.test(rest.target)) {
throw new RegistryError("invalid_target", "hdc target key contains invalid characters");
}
rest.platform = "harmonyos";
}
if (transport === "docker") {
if (!rest.container || !/^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/.test(rest.container)) {
throw new RegistryError("invalid_container", "docker computers need a valid container name");
}
// Spawned containers always run the Linux desktop image.
rest.platform = rest.platform ?? "linux";
}View on GitHub (pinned to 73e0f67d83)