thedotmack/claude-mem · error · AdapterRejectedInput

adapter rejected input: invalid_cwd

Error message

adapter rejected input: invalid_cwd

What it means

AdapterRejectedInput('invalid_cwd') thrown by antigravityCliAdapter.normalizeInput when the resolved working directory is not a non-empty string. isValidCwd only checks typeof === 'string' && length > 0, so the raw input cwd and all env fallbacks (GEMINI_CWD, GEMINI_PROJECT_DIR, CLAUDE_PROJECT_DIR, process.cwd()) must have failed to yield a usable value.

Solutions

  1. Pass a valid absolute directory string as cwd in the hook input JSON
  2. Export GEMINI_CWD or GEMINI_PROJECT_DIR with the project directory before invoking the CLI
  3. If cwd is meant to default, omit the cwd key entirely so process.cwd() is used instead of passing an empty string
  4. Wrap normalizeInput in try/catch on AdapterRejectedInput and log reason 'invalid_cwd' to diagnose which input field carried the bad value

Example fix

// before
const adapter = antigravityCliAdapter;
adapter.normalizeInput({ cwd: '' });
// after
adapter.normalizeInput({ cwd: '/absolute/path/to/project' });
Defensive patterns

Strategy: validation

Validate before calling

function safeCwd(v) { const c = typeof v === 'string' && v.length > 0 ? v : process.env.GEMINI_CWD || process.env.GEMINI_PROJECT_DIR || process.env.CLAUDE_PROJECT_DIR || process.cwd(); return c; }
if (!safeCwd(raw.cwd)) throw new Error('no usable 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') { /* fix cwd or skip */ } else throw e; }

Prevention

When it happens

Trigger: Calling the antigravity adapter with raw input where r.cwd is explicitly an empty string, whitespace-only, or a non-string (e.g. null, number), and none of GEMINI_CWD, GEMINI_PROJECT_DIR, or CLAUDE_PROJECT_DIR are set (process.cwd() itself always validates, so failure implies a corrupted/empty process.cwd or a cwd explicitly overridden with an empty value).

Common situations: Hook JSON from Antigravity containing "cwd": ""; test harnesses passing {cwd: undefined} while wiping env vars; Docker/CI environments where GEMINI_PROJECT_DIR points to a removed directory path that downstream code empties.

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/899a73d88b30f953. Report an issue: GitHub.

Appendix: source

Thrown at src/cli/adapters/antigravity-cli.ts:44

//
// formatOutput() must key its protojson response off the same raw payload, so we
// stash the last normalized raw input here (one normalizeInput→formatOutput
// cycle per hook process, so module state is safe).
let lastRawInput: Record<string, any> = {};

export const antigravityCliAdapter: PlatformAdapter = {
  normalizeInput(raw) {
    const r = (raw ?? {}) as any;
    lastRawInput = r;

    const cwd = r.workspacePaths?.[0]
      ?? r.cwd
      ?? process.env.GEMINI_CWD
      ?? process.env.GEMINI_PROJECT_DIR
      ?? process.env.CLAUDE_PROJECT_DIR
      ?? process.cwd();
    if (!isValidCwd(cwd)) {
      throw new AdapterRejectedInput('invalid_cwd');
    }

    const sessionId = r.conversationId
      ?? r.session_id
      ?? process.env.GEMINI_SESSION_ID
      ?? undefined;

    const transcriptPath = r.transcriptPath ?? r.transcript_path;

    const hasToolCall = Boolean(r.toolCall);
    const hasErrorKey = 'error' in r;
    // Pre/PostInvocation payloads are identical; both carry invocationNum and no
    // toolCall.
    const isInvocationEvent = 'invocationNum' in r && !hasToolCall;

    let toolName: string | undefined = r.toolCall?.name ?? r.tool_name;
    let toolInput: unknown = r.toolCall?.args ?? r.tool_input;
    let toolResponse: unknown = r.tool_response;

View on GitHub (pinned to d8bc9755e7)