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
- 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
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
- 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()
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
- adapter rejected input: invalid_cwd
- adapter rejected input: invalid_cwd
- adapter rejected input: invalid_cwd
- adapter rejected input: invalid_cwd
- adapter rejected input: invalid_cwd
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)