thedotmack/claude-mem · error · AdapterRejectedInput

adapter rejected input: invalid_cwd

Error message

adapter rejected input: invalid_cwd

What it means

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.

Solutions

  1. Pass a valid absolute directory string in r.cwd
  2. Delete the cwd key so the process.cwd() fallback is used
  3. If running in a container, chdir to an existing directory before invoking so process.cwd() is valid
  4. Catch AdapterRejectedInput and check .reason === 'invalid_cwd' to surface the misconfigured hook

Example fix

// before
codexAdapter.normalizeInput({ cwd: 123 });
// after
codexAdapter.normalizeInput({ cwd: '/absolute/path/to/project' });
Defensive patterns

Strategy: validation

Validate before calling

if (raw?.cwd !== undefined && (typeof raw.cwd !== 'string' || raw.cwd.length === 0)) delete raw.cwd; // or fix to a valid path before calling

Type guard

function hasValidCwd(v: unknown): v is string { return typeof v === 'string' && v.length > 0; }

Try / catch

try { adapter.normalizeInput(raw); } catch (e) { if (e instanceof AdapterRejectedInput && e.reason === 'invalid_cwd') { /* sanitize payload and retry */ } else throw e; }

Prevention

When it happens

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

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

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/9486d1708b3660ee. Report an issue: GitHub.

Appendix: source

Thrown at src/cli/adapters/codex.ts:64

function buildBaseOutput(result: HookResult): Record<string, unknown> {
  const output: Record<string, unknown> = {};
  if (result.continue !== undefined) output.continue = result.continue;
  if (result.systemMessage) output.systemMessage = result.systemMessage;
  if (result.decision === 'block') output.decision = 'block';
  if (result.reason) output.reason = result.reason;
  return output;
}

function inferOutputEvent(result: HookResult): CodexEventName | undefined {
  return eventName(result.hookSpecificOutput?.hookEventName);
}

export const codexAdapter: PlatformAdapter = {
  normalizeInput(raw): NormalizedHookInput {
    const r = (raw ?? {}) as Record<string, unknown>;
    const cwd = (typeof r.cwd === 'string' && r.cwd) || process.cwd();
    if (!isValidCwd(cwd)) {
      throw new AdapterRejectedInput('invalid_cwd');
    }

    const hookEventName = eventName(r.hook_event_name);
    const toolName = stringOrUndefined(r.tool_name);
    let toolInput = cloneToolInput(r.tool_input);

    if (hookEventName === 'PreToolUse' && toolName) {
      const filePaths = extractFilePaths(toolName, toolInput, cwd);
      if (filePaths.length > 0 && toolInput && typeof toolInput === 'object' && !Array.isArray(toolInput)) {
        toolInput = { ...(toolInput as Record<string, unknown>), filePaths };
      }
    }

    const source = r.source;
    const sessionSource =
      source === 'startup' || source === 'resume' || source === 'clear'
        ? source
        : undefined;

View on GitHub (pinned to d8bc9755e7)