thedotmack/claude-mem · error · AdapterRejectedInput

adapter rejected input: invalid_cwd

Error message

adapter rejected input: invalid_cwd

What it means

claudeCodeAdapter.normalizeInput throws AdapterRejectedInput('invalid_cwd') at the first check when the raw input cwd (or process.cwd() fallback) is not a non-empty string. This is the pre-normalization gate before resolveHookProjectPath is applied.

Solutions

  1. Supply a valid non-empty directory string as cwd in the hook input
  2. Check that the hook template does not substitute an empty variable for cwd (e.g. ${CLAUDE_PROJECT_DIR:-$PWD} instead of ${CLAUDE_PROJECT_DIR})
  3. Remove the cwd key to rely on process.cwd() fallback
  4. Catch AdapterRejectedInput and inspect .reason === 'invalid_cwd' to report the misconfigured hook

Example fix

// before
claudeCodeAdapter.normalizeInput({ cwd: process.env.CLAUDE_PROJECT_DIR ?? '' }); // '' if unset
// after
claudeCodeAdapter.normalizeInput({ cwd: process.env.CLAUDE_PROJECT_DIR || process.cwd() });
Defensive patterns

Strategy: validation

Validate before calling

if (typeof raw?.cwd !== 'string' || raw.cwd.length === 0) raw = { ...raw, cwd: process.cwd() };

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') { /* retry with process.cwd() */ } else throw e; }

Prevention

When it happens

Trigger: Invoking the claude-code adapter with raw where r.cwd is undefined, null, empty string, or a non-string type. Since process.cwd() is the fallback, the failure occurs when r.cwd is explicitly an invalid value (empty/non-string) or process.cwd() itself fails/returns empty.

Common situations: Claude Code hook payloads with "cwd": null; scripts passing process.env.CLAUDE_PROJECT_DIR which is empty string (empty string does not fall through ?? because '' is not nullish, so the empty value is used); misconfigured hook command templates substituting an empty variable.

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/37463fdb47b98679. Report an issue: GitHub.

Appendix: source

Thrown at src/cli/adapters/claude-code.ts:16

import type { PlatformAdapter, NormalizedHookInput, HookResult } from '../types.js';
import { AdapterRejectedInput, isValidCwd } from './errors.js';
import { resolveHookProjectPath } from '../../utils/project-name.js';

const MAX_AGENT_FIELD_LEN = 128;
const pickAgentField = (v: unknown): string | undefined =>
  typeof v === 'string' && v.length > 0 && v.length <= MAX_AGENT_FIELD_LEN ? v : undefined;
const pickStringField = (v: unknown): string | undefined =>
  typeof v === 'string' ? v : undefined;

export const claudeCodeAdapter: PlatformAdapter = {
  normalizeInput(raw) {
    const r = (raw ?? {}) as any;
    const inputCwd = r.cwd ?? process.cwd();
    if (!isValidCwd(inputCwd)) {
      throw new AdapterRejectedInput('invalid_cwd');
    }
    const cwd = resolveHookProjectPath(inputCwd);
    if (!isValidCwd(cwd)) {
      throw new AdapterRejectedInput('invalid_cwd');
    }
    return {
      sessionId: r.session_id ?? r.id ?? r.sessionId,
      cwd,
      prompt: r.prompt,
      toolName: r.tool_name,
      toolInput: r.tool_input,
      toolResponse: r.tool_response,
      toolUseId: typeof r.tool_use_id === 'string' ? r.tool_use_id : undefined,
      transcriptPath: r.transcript_path,
      reason: pickStringField(r.reason),
      agentId: pickAgentField(r.agent_id),
      agentType: pickAgentField(r.agent_type),
    };

View on GitHub (pinned to d8bc9755e7)