{"record":{"id":"24cef2b9823b53cc","repo":"openclaw/openclaw","slug":"invalid-codex-session-catalog-host-id-value","errorCode":null,"errorMessage":"invalid Codex session catalog host id: ${value}","messagePattern":"invalid Codex session catalog host id: (.+?)","errorType":"validation","errorClass":"CatalogParamsError","httpStatus":null,"severity":"error","filePath":"extensions/codex/src/session-catalog-parsing.ts","lineNumber":292,"sourceCode":"  return {\n    limitPerHost: normalizeLimit(params.limitPerHost, \"limitPerHost\"),\n    ...(search ? { search } : {}),\n    ...(hostIds && hostIds.length > 0 ? { hostIds } : {}),\n    ...(cursors && Object.keys(cursors).length > 0 ? { cursors } : {}),\n  };\n}\n\nfunction readHostId(value: unknown): string {\n  if (typeof value !== \"string\") {\n    throw new CatalogParamsError(\"Codex session catalog host ids must be strings\");\n  }\n  const hostId = value.trim();\n  if (\n    hostId.length === 0 ||\n    hostId.length > MAX_HOST_ID_LENGTH ||\n    (!hostId.startsWith(\"gateway:\") && !hostId.startsWith(\"node:\"))\n  ) {\n    throw new CatalogParamsError(`invalid Codex session catalog host id: ${value}`);\n  }\n  return hostId;\n}\n\nexport function parseJsonParams(paramsJSON?: string | null): unknown {\n  if (!paramsJSON?.trim()) {\n    return {};\n  }\n  try {\n    return JSON.parse(paramsJSON) as unknown;\n  } catch (error) {\n    throw new Error(\"Codex session catalog parameters must be valid JSON\", { cause: error });\n  }\n}\n\nfunction readFiniteNumber(value: unknown): number | undefined {\n  return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/openclaw/openclaw/blob/01804a75319da4b69c9ab98ceaa30477e22b8c0b/extensions/codex/src/session-catalog-parsing.ts#L274-L310","documentation":"Thrown by readHostId when a hostIds entry, after trimming, is empty, longer than MAX_HOST_ID_LENGTH (256), or does not start with 'gateway:' or 'node:'. This is the array-entry counterpart of the cursors-key validation.","triggerScenarios":"Passing hostIds like [\"localhost\"], [\"   \"], [\"node:\"], or an unprefixed node uuid.","commonSituations":"Forgetting the prefix when forwarding a raw node id; including a placeholder empty string from a UI dropdown.","solutions":["Use the full prefixed host id form: 'gateway:local' or 'node:<nodeId>'.","Filter out empty/whitespace entries before serializing."],"exampleFix":"// before\nconst hostIds = [nodeId];\n// after\nconst hostIds = [`node:${nodeId}`];","handlingStrategy":"validation","validationCode":"function isPrefixedHost(value: string): boolean {\n  const t = value.trim();\n  return t.length > 0 && t.length <= 256 && (t.startsWith(\"gateway:\") || t.startsWith(\"node:\"));\n}\nparams.hostIds = (params.hostIds ?? []).filter(isPrefixedHost);","typeGuard":"function isHostId(value: unknown): value is string {\n  if (typeof value !== \"string\") return false;\n  const t = value.trim();\n  return t.length > 0 && t.length <= 256 && (t.startsWith(\"gateway:\") || t.startsWith(\"node:\"));\n}","tryCatchPattern":null,"preventionTips":["Pull hostIds from the catalog's host list rather than constructing them by hand.","Always wrap node ids with the 'node:' prefix."],"tags":["validation","codex","session-catalog","input-validation"],"backgroundTag":null,"analyzedSha":"01804a75319da4b69c9ab98ceaa30477e22b8c0b","analyzedAt":"2026-08-12T04:37:58.197Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}