{"record":{"id":"de70ddd42000cf61","repo":"Hmbown/CodeWhale","slug":"invalid-id","errorCode":"invalid_id","errorMessage":"computer id must match \" + ID_RE","messagePattern":"computer id must match \" \\+ ID_RE","errorType":"validation","errorClass":"RegistryError","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/registry.mjs","lineNumber":79,"sourceCode":"  const c = reg.computers[id];\n  if (!c) throw new RegistryError(\"unknown_computer\", `no computer registered with id \"${id}\". Use computer_list.`);\n  return c;\n}\n\nexport function active() { return get(list().active); }\n\n/** Switch the active computer. Returns the computer entry. */\nexport function switchTo(id) {\n  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\") {","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/registry.mjs#L61-L97","documentation":"RegistryError \"invalid_id\": register() rejects any computer id that is missing or does not match ID_RE. The registry uses ids as object keys in the saved computers map and exposes them to tool calls, so only a constrained character set is accepted. This validation runs before any transport-specific checks, so it fires first when both id and transport are bad.","triggerScenarios":"Calling register({ id: undefined, ... }), register({ id: \"\", ... }), or register({ id: \"my computer!\", ... }) with characters outside ID_RE (e.g. spaces, slashes, uppercase-sensitive patterns, colons).","commonSituations":"Copy-pasting a hostname or device serial containing colons/spaces into the id field; building an id from user input without sanitizing; forgetting to pass id entirely when spreading config into register().","solutions":["Choose an id that matches ID_RE — use letters, digits, and simple separators like dashes (e.g. \"desk-pc\", \"lab-ssh01\").","Check the exact pattern by inspecting ID_RE at the top of registry.mjs and conform to it.","Sanitize or slugify any externally supplied id before passing it to register().","Ensure id is a non-empty string (not undefined/null/number) in the object passed to register()."],"exampleFix":"// before\nregister({ id: inputHostname, transport: \"ssh\", host: inputHostname });\n// after\nconst id = inputHostname.replace(/[^A-Za-z0-9._-]/g, \"-\");\nregister({ id, transport: \"ssh\", host: inputHostname });","handlingStrategy":"validation","validationCode":"// const ID_RE = <pattern from registry.mjs>;\nfunction validId(id) { return typeof id === \"string\" && id.length > 0 && ID_RE.test(id); }\nif (!validId(id)) throw new Error(`id \"${id}\" must match ${ID_RE}`);","typeGuard":"const isRegistryId = (v) => typeof v === \"string\" && v.length > 0 && /^[A-Za-z0-9._-]+$/.test(v);","tryCatchPattern":"try {\n  register({ id, transport, ...rest });\n} catch (e) {\n  if (e instanceof RegistryError && e.code === \"invalid_id\") {\n    throw new Error(`Bad computer id \"${id}\": use letters/digits/dots/dashes`);\n  }\n  throw e;\n}","preventionTips":["Slugify externally supplied ids before registering","Keep ids to [A-Za-z0-9._-] by convention","Never derive ids from free-form user input without sanitizing","Check ID_RE in registry.mjs when in doubt"],"tags":["validation","registry","javascript","input-sanitization"],"backgroundTag":"invalid-identifier-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"}