Yeachan-Heo/oh-my-codex · error · Error

invalid detached leader payload

Error message

invalid detached leader payload

What it means

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.

Source

Thrown at src/cli/index.ts:6947

}



interface DetachedLeaderPayload {
  cwd: string;
  sessionName: string;
  sessionId: string;
  codexCmd: string;
  codexHomeOverride?: string;
  projectLocalCodexHomeForCleanup?: string;
  runtimeCodexHomeForCleanup?: string;
  parentEnv?: Record<string, string>;
  readyPath?: string;
  preLaunchOptions: DetachedLeaderPreLaunchOptions;
}

export function decodeDetachedLeaderPayload(encoded: string | undefined): DetachedLeaderPayload {
  if (!encoded || !/^[A-Za-z0-9_-]+$/.test(encoded)) throw new Error("invalid detached leader payload");
  let value: unknown;
  try { value = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8")); } catch { throw new Error("invalid detached leader payload"); }
  if (!value || typeof value !== "object") throw new Error("invalid detached leader payload");
  const payload = value as Record<string, unknown>;
  const options = payload.preLaunchOptions;
  if (typeof payload.cwd !== "string" || typeof payload.sessionName !== "string" || typeof payload.sessionId !== "string" ||
    typeof payload.codexCmd !== "string" || !options || typeof options !== "object" ||
    typeof (options as Record<string, unknown>).enableNotifyFallbackAuthority !== "boolean" ||
    typeof (options as Record<string, unknown>).worktreeDirty !== "boolean" ||
    typeof (options as Record<string, unknown>).shouldAttach !== "boolean") throw new Error("invalid detached leader payload");
  const notifyTempContract = (options as Record<string, unknown>).notifyTempContract;
  if (notifyTempContract !== undefined && (!notifyTempContract || typeof notifyTempContract !== "object")) throw new Error("invalid detached leader payload");
  const parentEnv = payload.parentEnv;
  if (parentEnv !== undefined && (!parentEnv || typeof parentEnv !== "object" ||
    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")))) {
    throw new Error("invalid detached leader parent environment");
  }
  return {

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Encode with base64url, not standard base64: Buffer.from(JSON.stringify(p)).toString('base64url')
  2. Pass the payload as a single quoted argv/env value to avoid shell mangling or truncation
  3. Prefer letting OMX construct and pass the payload itself rather than building it manually
  4. Validate length and charset before invoking if generating payloads programmatically

Example fix

// before
const encoded = Buffer.from(json).toString("base64"); // may include + and =

// after
const encoded = Buffer.from(json).toString("base64url");
Defensive patterns

Strategy: type-guard

Validate before calling

function isBase64Url(s: string): boolean { return /^[A-Za-z0-9_-]+$/.test(s); }
if (!payload || !isBase64Url(payload)) throw new TypeError("payload must be base64url without padding");

Type guard

function isBase64UrlPayload(s: unknown): s is string { return typeof s === "string" && s.length > 0 && /^[A-Za-z0-9_-]+$/.test(s); }

Try / catch

try { decodeDetachedLeaderPayload(encoded); } catch (e) { if (e.message === "invalid detached leader payload") { /* re-encode with base64url and retry */ } }

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/f85d9f45d8b92b68. Report an issue: GitHub.