{"record":{"id":"20f07c67d72b97bd","repo":"stablyai/orca","slug":"invalid-localhost-label-route","errorCode":null,"errorMessage":"Invalid localhost label route.","messagePattern":"Invalid localhost label route\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ipc/localhost-worktree-labels.ts","lineNumber":74,"sourceCode":"    }\n    const advertisedUrl = 'advertisedUrl' in port ? port.advertisedUrl : undefined\n    if (!advertisedUrl) {\n      return false\n    }\n    try {\n      return normalizeLocalhostHostname(new URL(advertisedUrl).hostname) === targetHost\n    } catch {\n      return false\n    }\n  })\n  if (!matches) {\n    throw new Error('Localhost label target is not an allowed workspace port.')\n  }\n}\n\nfunction parseRegisterArgs(value: unknown): LocalhostWorktreeLabelRoute {\n  if (!value || typeof value !== 'object') {\n    throw new Error('Invalid localhost label route.')\n  }\n  const candidate = value as Record<string, unknown>\n  const targetUrl = readRequiredString(candidate.targetUrl, 'targetUrl')\n  const projectName = readRequiredString(candidate.projectName, 'projectName')\n  const worktreeName = readRequiredString(candidate.worktreeName, 'worktreeName')\n  return {\n    targetUrl,\n    projectName,\n    worktreeName,\n    repoId: readOptionalString(candidate.repoId),\n    worktreeId: readOptionalString(candidate.worktreeId)\n  }\n}\n\nfunction readRequiredString(value: unknown, field: string): string {\n  if (typeof value !== 'string' || value.trim().length === 0) {\n    throw new Error(`Invalid localhost label ${field}.`)\n  }","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/localhost-worktree-labels.ts#L56-L92","documentation":"Thrown by parseRegisterArgs when the IPC argument value is not a non-null object. parseRegisterArgs expects a LocalhostWorktreeLabelRoute-shaped object (targetUrl, projectName, worktreeName, repoId?, worktreeId?). If the renderer sends a primitive, null, or omits the argument entirely, the object check fails before any field validation.","triggerScenarios":"Calling the localhost-worktree-labels register IPC with a primitive argument (string/number), null, undefined, or an array. The handler then reads candidate.targetUrl etc., but the top-level object guard rejects first.","commonSituations":"Renderer sends the route fields as separate positional args instead of a single object. A serialization bug flattens the object. The call site was refactored and the argument shape drifted.","solutions":["Pass a single object containing targetUrl, projectName, and worktreeName (plus optional repoId/worktreeId) as the IPC argument.","Verify the renderer's invoke call wraps the payload as one object.","Add a TypeScript type at the call boundary so shape drift is caught at compile time."],"exampleFix":"// before\nawait ipc.call('localhostLabel:register', targetUrl, projectName, worktreeName)\n\n// after\nawait ipc.call('localhostLabel:register', { targetUrl, projectName, worktreeName })","handlingStrategy":"type-guard","validationCode":"if (!value || typeof value !== 'object' || Array.isArray(value)) {\n  throw new Error('Route argument must be an object')\n}","typeGuard":"function isRouteObject(value: unknown): value is Record<string, unknown> {\n  return typeof value === 'object' && value !== null && !Array.isArray(value)\n}","tryCatchPattern":null,"preventionTips":["Pass the route as a single object argument, not positional values.","Type the IPC call argument at the boundary so shape drift fails to compile.","Double-check refactored call sites preserve the object wrapper."],"tags":["validation","ipc","localhost","serialization"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}