thedotmack/claude-mem · critical · Error
plugin/.mcp.json mcp-search launcher must include Codex cach
Error message
plugin/.mcp.json mcp-search launcher must include Codex cache fallback for hosts that do not inject PLUGIN_ROOT
What it means
Loads plugin/.mcp.json, joins the mcp-search server's args, and asserts the resulting command contains the literal '.codex/plugins/cache/claude-mem-local/claude-mem'. This is the Codex cache fallback path used by hosts that don't inject PLUGIN_ROOT; without it the mcp-search launcher fails to locate the binary under Codex. The error names the missing fragment.
Source
Thrown at scripts/build-hooks.js:746
for (const rootKey of Object.keys(codexHooks)) {
if (!validCodexHookRootKeys.has(rootKey)) {
throw new Error(`plugin/hooks/codex-hooks.json contains unsupported Codex root key: ${rootKey}`);
}
}
for (const eventName of Object.keys(codexHooks.hooks ?? {})) {
if (!validCodexHookEvents.has(eventName)) {
throw new Error(`plugin/hooks/codex-hooks.json contains unknown Codex hook event: ${eventName}`);
}
}
const codexMarketplace = JSON.parse(fs.readFileSync('.agents/plugins/marketplace.json', 'utf-8'));
const claudeMemMarketplaceEntry = (codexMarketplace.plugins ?? []).find((plugin) => plugin.name === 'claude-mem');
if (claudeMemMarketplaceEntry?.source?.path !== './plugin') {
throw new Error('.agents/plugins/marketplace.json must point claude-mem source.path at ./plugin so Codex loads the bundled plugin root');
}
const bundledMcp = JSON.parse(fs.readFileSync('plugin/.mcp.json', 'utf-8'));
const mcpSearchCommand = bundledMcp.mcpServers?.['mcp-search']?.args?.join(' ') ?? '';
if (!mcpSearchCommand.includes('.codex/plugins/cache/claude-mem-local/claude-mem')) {
throw new Error('plugin/.mcp.json mcp-search launcher must include Codex cache fallback for hosts that do not inject PLUGIN_ROOT');
}
if (!mcpSearchCommand.includes('plugins/cache/thedotmack/claude-mem')) {
throw new Error('plugin/.mcp.json mcp-search launcher must include Claude cache fallback for hosts that do not inject PLUGIN_ROOT');
}
console.log('✓ All required distribution files present');
await verifyShellTemplateCanonical();
console.log('\n✅ All build targets compiled successfully!');
console.log(` Output: ${hooksDir}/`);
console.log(` - Worker: worker-service.cjs`);
console.log(` - Server: server-service.cjs`);
console.log(` - MCP Server: mcp-server.cjs`);
console.log(` - Context Generator: context-generator.cjs`);
console.log(` - Transcript Watcher: transcript-watcher.cjs`);
console.log(` Output: ${npxCliOutDir}/`);
console.log(` - NPX CLI: index.js`);
if (fs.existsSync('openclaw/dist/index.js')) {View on GitHub (pinned to d768ba3643)
Solutions
- Restore the '.codex/plugins/cache/claude-mem-local/claude-mem' fragment in the mcp-search launcher string in plugin/.mcp.json.
- If the launcher is generator-produced, ensure src/build/hook-shell-template.ts still emits the Codex cache fallback branch, then run node scripts/build-hooks.js --write-shell-templates.
- Re-run the build; the substring check at scripts/build-hooks.js:744-747 must pass.
Example fix
// before: launcher lacks the Codex cache fallback "args": ["...", "PLUGIN_ROOT="$PLUGIN_ROOT" exec \"$PLUGIN_ROOT/mcp-search\""] // after: include the Codex cache path for hosts without PLUGIN_ROOT "args": ["...", "... || exec \".codex/plugins/cache/claude-mem-local/claude-mem/mcp-search\""]
Defensive patterns
Strategy: validation
Validate before calling
const mcp = JSON.parse(fs.readFileSync('plugin/.mcp.json','utf8'));
const cmd = (mcp.mcpServers?.['mcp-search']?.args ?? []).join(' ');
if (!cmd.includes('.codex/plugins/cache/claude-mem-local/claude-mem')) {
throw new Error('mcp-search launcher missing Codex cache fallback');
} Try / catch
// Build-time only. Restore the Codex cache-fallback fragment in the launcher, // or regenerate via --write-shell-templates after fixing the generator.
Prevention
- Treat the mcp-search launcher as generator-owned; never hand-edit.
- When modifying buildShellCommand, preserve both cache-fallback branches (Codex + Claude).
- Add a CI assertion for both fallback substrings.
When it happens
Trigger: Editing the mcp-search launcher in plugin/.mcp.json and dropping or rewriting the Codex cache fallback fragment. Regenerating shell templates with a buildShellCommand that omits the Codex cache branch.
Common situations: Simplifying the launcher to assume PLUGIN_ROOT is always set (it isn't, under Codex). Removing cache-fallback branches as 'dead code'. A generator change that drops the Codex path.
Related errors
- plugin/.mcp.json mcp-search launcher must include Claude cac
- .agents/plugins/marketplace.json must point claude-mem sourc
- plugin/hooks/codex-hooks.json contains unsupported Codex roo
- plugin/hooks/codex-hooks.json contains unknown Codex hook ev
- Hand-edited shell string detected in ${filePath} (mcp-search
AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12).
Data as JSON: /api/errors/7b0d832c5f968127.
Report an issue: GitHub.