{"record":{"id":"f85d9f45d8b92b68","repo":"Yeachan-Heo/oh-my-codex","slug":"invalid-detached-leader-payload","errorCode":null,"errorMessage":"invalid detached leader payload","messagePattern":"invalid detached leader payload","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cli/index.ts","lineNumber":6947,"sourceCode":"}\n\n\n\ninterface DetachedLeaderPayload {\n  cwd: string;\n  sessionName: string;\n  sessionId: string;\n  codexCmd: string;\n  codexHomeOverride?: string;\n  projectLocalCodexHomeForCleanup?: string;\n  runtimeCodexHomeForCleanup?: string;\n  parentEnv?: Record<string, string>;\n  readyPath?: string;\n  preLaunchOptions: DetachedLeaderPreLaunchOptions;\n}\n\nexport function decodeDetachedLeaderPayload(encoded: string | undefined): DetachedLeaderPayload {\n  if (!encoded || !/^[A-Za-z0-9_-]+$/.test(encoded)) throw new Error(\"invalid detached leader payload\");\n  let value: unknown;\n  try { value = JSON.parse(Buffer.from(encoded, \"base64url\").toString(\"utf8\")); } catch { throw new Error(\"invalid detached leader payload\"); }\n  if (!value || typeof value !== \"object\") throw new Error(\"invalid detached leader payload\");\n  const payload = value as Record<string, unknown>;\n  const options = payload.preLaunchOptions;\n  if (typeof payload.cwd !== \"string\" || typeof payload.sessionName !== \"string\" || typeof payload.sessionId !== \"string\" ||\n    typeof payload.codexCmd !== \"string\" || !options || typeof options !== \"object\" ||\n    typeof (options as Record<string, unknown>).enableNotifyFallbackAuthority !== \"boolean\" ||\n    typeof (options as Record<string, unknown>).worktreeDirty !== \"boolean\" ||\n    typeof (options as Record<string, unknown>).shouldAttach !== \"boolean\") throw new Error(\"invalid detached leader payload\");\n  const notifyTempContract = (options as Record<string, unknown>).notifyTempContract;\n  if (notifyTempContract !== undefined && (!notifyTempContract || typeof notifyTempContract !== \"object\")) throw new Error(\"invalid detached leader payload\");\n  const parentEnv = payload.parentEnv;\n  if (parentEnv !== undefined && (!parentEnv || typeof parentEnv !== \"object\" ||\n    Object.entries(parentEnv).some(([key, value]) => !SHELL_ENV_NAME_PATTERN.test(key) || DETACHED_SESSION_PANE_ENV_KEYS.has(key) || typeof value !== \"string\" || value.includes(\"\\0\")))) {\n    throw new Error(\"invalid detached leader parent environment\");\n  }\n  return {","sourceCodeStart":6929,"sourceCodeEnd":6965,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/index.ts#L6929-L6965","documentation":"decodeDetachedLeaderPayload validates the base64url-encoded leader payload passed to the detached leader. The first throw rejects payloads that are empty or contain characters outside the base64url alphabet [A-Za-z0-9_-] before any decoding is attempted.","triggerScenarios":"The encoded payload argument is undefined/empty, or was mangled in transit — shell quoting stripping characters, a non-base64url string passed by a wrapper, truncation through env var or argv length limits, or manual construction of the payload with padding '+'/'=' characters (standard base64 instead of base64url).","commonSituations":"Manually invoking the detached leader subcommand with a hand-encoded payload; scripts that pipe the payload through shells that mangle it; using standard base64 (with +/=) instead of base64url encoding.","solutions":["Encode with base64url, not standard base64: Buffer.from(JSON.stringify(p)).toString('base64url')","Pass the payload as a single quoted argv/env value to avoid shell mangling or truncation","Prefer letting OMX construct and pass the payload itself rather than building it manually","Validate length and charset before invoking if generating payloads programmatically"],"exampleFix":"// before\nconst encoded = Buffer.from(json).toString(\"base64\"); // may include + and =\n\n// after\nconst encoded = Buffer.from(json).toString(\"base64url\");","handlingStrategy":"type-guard","validationCode":"function isBase64Url(s: string): boolean { return /^[A-Za-z0-9_-]+$/.test(s); }\nif (!payload || !isBase64Url(payload)) throw new TypeError(\"payload must be base64url without padding\");","typeGuard":"function isBase64UrlPayload(s: unknown): s is string { return typeof s === \"string\" && s.length > 0 && /^[A-Za-z0-9_-]+$/.test(s); }","tryCatchPattern":"try { decodeDetachedLeaderPayload(encoded); } catch (e) { if (e.message === \"invalid detached leader payload\") { /* re-encode with base64url and retry */ } }","preventionTips":["Always encode with Buffer.toString('base64url'), never 'base64'","Pass payloads as a single quoted argv or env value","Round-trip-test generated payloads before shipping them"],"tags":["detached-launch","payload","base64url","validation"],"backgroundTag":"malformed-encoded-payload","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}