EveryInc/compound-engineering-plugin · error · Error
Local skill mode cannot represent Codex runtime components:
Error message
Local skill mode cannot represent Codex runtime components: ${unsupported.join(", ")}. Update the developer workflow before using it. What it means
Local skill mode can only link the skills directory; it cannot represent Codex runtime components. If .codex-plugin/plugin.json defines any of apps, hooks, or mcpServers, the library refuses with this error listing the offending keys, so the developer updates the workflow before linking, avoiding a half-installed local mode.
Source
Thrown at src/dev/codex-dev.ts:140
async function assertCompoundEngineeringRepo(repoRoot: string): Promise<void> {
const packageJson = await readJson(path.join(repoRoot, "package.json"))
if (packageJson.name !== "compound-engineering") {
throw new Error(`${repoRoot} is not the compound-engineering repository`)
}
const pluginJson = await readJson(path.join(repoRoot, ".codex-plugin", "plugin.json"))
if (pluginJson.name !== "compound-engineering") {
throw new Error(`${repoRoot} is not the compound-engineering repository`)
}
const skills = pluginJson.skills
if (typeof skills !== "string" || path.resolve(repoRoot, skills) !== path.join(repoRoot, "skills")) {
throw new Error("The Codex plugin manifest does not point at this repository's skills directory")
}
const unsupported = ["apps", "hooks", "mcpServers"].filter((key) => pluginJson[key] !== undefined)
if (unsupported.length > 0) {
throw new Error(
`Local skill mode cannot represent Codex runtime components: ${unsupported.join(", ")}. Update the developer workflow before using it.`,
)
}
try {
const defaultHooks = await fs.stat(path.join(repoRoot, "hooks", "hooks.json"))
if (defaultHooks.isFile()) {
throw new Error(
"Local skill mode cannot represent default Codex hooks at hooks/hooks.json. Update the developer workflow before using it.",
)
}
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error
}
}
async function listSkills(skillsRoot: string): Promise<string[]> {
const entries = await fs.readdir(skillsRoot, { withFileTypes: true })View on GitHub (pinned to c9c10f8c75)
Solutions
- Check which keys are listed: jq '{apps, hooks, mcpServers}' .codex-plugin/plugin.json.
- Remove the listed keys from the manifest (or git restore it) if they are not needed.
- If the components are genuinely required, do not use local skill mode — use bun run codex:dev -- remote (marketplace install) until the dev workflow supports them.
Example fix
// before: .codex-plugin/plugin.json
{ "name": "compound-engineering", "skills": "skills", "mcpServers": { "docs": {} } }
// after
{ "name": "compound-engineering", "skills": "skills" } Defensive patterns
Strategy: validation
Validate before calling
const m = JSON.parse(await (await import("node:fs/promises")).readFile(".codex-plugin/plugin.json", "utf8"))
const bad = ["apps", "hooks", "mcpServers"].filter((k) => m[k] !== undefined)
if (bad.length > 0) throw new Error(`Remove ${bad.join(", ")} before codex:dev -- local`) Type guard
function isSkillsOnlyManifest(m: Record<string, unknown>): boolean {
return ["apps", "hooks", "mcpServers"].every((k) => m[k] === undefined)
} Try / catch
try {
await switchToLocal()
} catch (error) {
if ((error as Error).message.startsWith("Local skill mode cannot represent Codex runtime components")) {
console.error("Use bun run codex:dev -- remote, or remove the runtime keys from the manifest")
} else throw error
} Prevention
- Check jq '{apps,hooks,mcpServers}' .codex-plugin/plugin.json before local mode.
- Branch work that adds runtime components should use codex:dev -- remote, not local mode.
- Re-run release:validate after merging upstream manifest changes.
When it happens
Trigger: resolveCodexDevContext -> assertCompoundEngineeringRepo finds pluginJson["apps"], pluginJson["hooks"], or pluginJson["mcpServers"] defined (non-undefined) in .codex-plugin/plugin.json (src/dev/codex-dev.ts:140).
Common situations: A developer added MCP servers or hooks to the Codex manifest for a new feature and then ran codex:dev -- local; merging an upstream change that introduced runtime components; a stale/hand-edited manifest carrying legacy keys.
Related errors
- The Codex plugin manifest does not point at this repository'
- Local skill mode cannot represent default Codex hooks at hoo
- Dropping unsafe Pi install-manifest entry in ${manifestPath}
- Cleanup currently supports only the compound-engineering plu
- Unknown cleanup target: ${target}. Use one of: ${cleanupTarg
AI-assisted analysis of EveryInc/compound-engineering-plugin@c9c10f8c75 (2026-08-31).
Data as JSON: /api/errors/48cdf1209998fb3d.
Report an issue: GitHub.