{"record":{"id":"899a73d88b30f953","repo":"thedotmack/claude-mem","slug":"adapter-rejected-input-invalid-cwd","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/antigravity-cli.ts","lineNumber":44,"sourceCode":"//\n// formatOutput() must key its protojson response off the same raw payload, so we\n// stash the last normalized raw input here (one normalizeInput→formatOutput\n// cycle per hook process, so module state is safe).\nlet lastRawInput: Record<string, any> = {};\n\nexport const antigravityCliAdapter: PlatformAdapter = {\n  normalizeInput(raw) {\n    const r = (raw ?? {}) as any;\n    lastRawInput = r;\n\n    const cwd = r.workspacePaths?.[0]\n      ?? r.cwd\n      ?? process.env.GEMINI_CWD\n      ?? process.env.GEMINI_PROJECT_DIR\n      ?? process.env.CLAUDE_PROJECT_DIR\n      ?? process.cwd();\n    if (!isValidCwd(cwd)) {\n      throw new AdapterRejectedInput('invalid_cwd');\n    }\n\n    const sessionId = r.conversationId\n      ?? r.session_id\n      ?? process.env.GEMINI_SESSION_ID\n      ?? undefined;\n\n    const transcriptPath = r.transcriptPath ?? r.transcript_path;\n\n    const hasToolCall = Boolean(r.toolCall);\n    const hasErrorKey = 'error' in r;\n    // Pre/PostInvocation payloads are identical; both carry invocationNum and no\n    // toolCall.\n    const isInvocationEvent = 'invocationNum' in r && !hasToolCall;\n\n    let toolName: string | undefined = r.toolCall?.name ?? r.tool_name;\n    let toolInput: unknown = r.toolCall?.args ?? r.tool_input;\n    let toolResponse: unknown = r.tool_response;","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/cli/adapters/antigravity-cli.ts#L26-L62","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Pass a valid absolute directory string as cwd in the hook input JSON","Export GEMINI_CWD or GEMINI_PROJECT_DIR with the project directory before invoking the CLI","If cwd is meant to default, omit the cwd key entirely so process.cwd() is used instead of passing an empty string","Wrap normalizeInput in try/catch on AdapterRejectedInput and log reason 'invalid_cwd' to diagnose which input field carried the bad value"],"exampleFix":"// before\nconst adapter = antigravityCliAdapter;\nadapter.normalizeInput({ cwd: '' });\n// after\nadapter.normalizeInput({ cwd: '/absolute/path/to/project' });","handlingStrategy":"validation","validationCode":"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; }\nif (!safeCwd(raw.cwd)) throw new Error('no usable cwd');","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') { /* fix cwd or skip */ } else throw e; }","preventionTips":["Always pass an absolute directory string as cwd","Never pass empty-string cwd; omit the key to use the process.cwd() fallback","Set GEMINI_CWD/GEMINI_PROJECT_DIR in CI environments","Sanitize hook JSON types before invoking the adapter"],"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"}