{"record":{"id":"9486d1708b3660ee","repo":"thedotmack/claude-mem","slug":"adapter-rejected-input-invalid-cwd-codex","errorCode":null,"errorMessage":"adapter rejected input: invalid_cwd","messagePattern":"adapter rejected input: invalid_cwd","errorType":"validation","errorClass":"AdapterRejectedInput","httpStatus":null,"severity":"error","filePath":"src/cli/adapters/codex.ts","lineNumber":64,"sourceCode":"function buildBaseOutput(result: HookResult): Record<string, unknown> {\n  const output: Record<string, unknown> = {};\n  if (result.continue !== undefined) output.continue = result.continue;\n  if (result.systemMessage) output.systemMessage = result.systemMessage;\n  if (result.decision === 'block') output.decision = 'block';\n  if (result.reason) output.reason = result.reason;\n  return output;\n}\n\nfunction inferOutputEvent(result: HookResult): CodexEventName | undefined {\n  return eventName(result.hookSpecificOutput?.hookEventName);\n}\n\nexport const codexAdapter: PlatformAdapter = {\n  normalizeInput(raw): NormalizedHookInput {\n    const r = (raw ?? {}) as Record<string, unknown>;\n    const cwd = (typeof r.cwd === 'string' && r.cwd) || process.cwd();\n    if (!isValidCwd(cwd)) {\n      throw new AdapterRejectedInput('invalid_cwd');\n    }\n\n    const hookEventName = eventName(r.hook_event_name);\n    const toolName = stringOrUndefined(r.tool_name);\n    let toolInput = cloneToolInput(r.tool_input);\n\n    if (hookEventName === 'PreToolUse' && toolName) {\n      const filePaths = extractFilePaths(toolName, toolInput, cwd);\n      if (filePaths.length > 0 && toolInput && typeof toolInput === 'object' && !Array.isArray(toolInput)) {\n        toolInput = { ...(toolInput as Record<string, unknown>), filePaths };\n      }\n    }\n\n    const source = r.source;\n    const sessionSource =\n      source === 'startup' || source === 'resume' || source === 'clear'\n        ? source\n        : undefined;","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/cli/adapters/codex.ts#L46-L82","documentation":"codexAdapter.normalizeInput throws AdapterRejectedInput('invalid_cwd') when the selected cwd (r.cwd if a non-empty string, otherwise process.cwd()) fails isValidCwd. Because the fallback is process.cwd(), this fires mainly when r.cwd is explicitly provided but empty or a non-string, or when process.cwd() itself is unusable.","triggerScenarios":"Calling the codex adapter with raw where r.cwd is '' or a non-string; empty-string cwd is particularly sneaky because (typeof r.cwd === 'string' && r.cwd) is falsy so an empty string does fall through to process.cwd() — failure then implies a broken process.cwd() or non-string cwd types like objects/numbers.","commonSituations":"Codex hook JSON with \"cwd\": 123 or an object; sandboxed runners where the process's working directory was deleted (process.cwd() throws/returns empty); upstream Codex CLI version changes renaming the cwd field.","solutions":["Pass a valid absolute directory string in r.cwd","Delete the cwd key so the process.cwd() fallback is used","If running in a container, chdir to an existing directory before invoking so process.cwd() is valid","Catch AdapterRejectedInput and check .reason === 'invalid_cwd' to surface the misconfigured hook"],"exampleFix":"// before\ncodexAdapter.normalizeInput({ cwd: 123 });\n// after\ncodexAdapter.normalizeInput({ cwd: '/absolute/path/to/project' });","handlingStrategy":"validation","validationCode":"if (raw?.cwd !== undefined && (typeof raw.cwd !== 'string' || raw.cwd.length === 0)) delete raw.cwd; // or fix to a valid path before calling","typeGuard":"function hasValidCwd(v: unknown): v is string { return typeof v === 'string' && v.length > 0; }","tryCatchPattern":"try { adapter.normalizeInput(raw); } catch (e) { if (e instanceof AdapterRejectedInput && e.reason === 'invalid_cwd') { /* sanitize payload and retry */ } else throw e; }","preventionTips":["Ensure upstream emits cwd as a string, never a number/object","chdir to a valid directory in sandboxed/container runners","Omit cwd to fall back to process.cwd()"],"tags":["input-validation","adapter","cwd"],"backgroundTag":"invalid-argument-value","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}