EveryInc/compound-engineering-plugin · error · Error
Local skill mode cannot represent default Codex hooks at hoo
Error message
Local skill mode cannot represent default Codex hooks at hooks/hooks.json. Update the developer workflow before using it.
What it means
Even if the manifest declares no hooks, the library additionally checks whether a default hooks file exists at <repoRoot>/hooks/hooks.json. If that file exists, local skill mode could not represent it once installed, so it throws this error. ENOENT (no such file) is treated as the happy path and swallowed.
Source
Thrown at src/dev/codex-dev.ts:148
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 })
const names: string[] = []
for (const entry of entries) {
if (!entry.isDirectory() && !entry.isSymbolicLink()) continue
try {
const stat = await fs.stat(path.join(skillsRoot, entry.name, "SKILL.md"))
if (stat.isFile()) names.push(entry.name)
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw errorView on GitHub (pinned to c9c10f8c75)
Solutions
- Check the file: ls hooks/hooks.json — if it is experimental leftovers, remove it or move it out of the checkout.
- git restore/rebase away the branch that added hooks/hooks.json if it is not intended on this branch.
- Use bun run codex:dev -- remote while the repo carries default hooks.
Example fix
// before: repo layout hooks/hooks.json // present skills/ // after hooks/ // no hooks.json (or directory removed) skills/
Defensive patterns
Strategy: validation
Validate before calling
import { stat } from "node:fs/promises"
try {
const s = await stat("hooks/hooks.json")
if (s.isFile()) throw new Error("hooks/hooks.json present; local mode unavailable")
} catch (e) {
if ((e as NodeJS.ErrnoException).code !== "ENOENT") throw e
} Try / catch
try {
await switchToLocal()
} catch (error) {
if ((error as Error).message.includes("default Codex hooks at hooks/hooks.json")) {
console.error("Remove or move hooks/hooks.json, or use codex:dev -- remote")
} else throw error
} Prevention
- Keep hook prototypes outside the repo (or in an untracked scratch dir) while using local mode.
- After rebasing onto branches that add hooks/, re-check hooks/hooks.json existence.
- Add hooks/hooks.json to a pre-flight check in scripts that automate local mode.
When it happens
Trigger: fs.stat(<repoRoot>/hooks/hooks.json) succeeds and isFile() is true during assertCompoundEngineeringRepo (src/dev/codex-dev.ts:148); the repo contains a hooks/hooks.json file while running codex:dev -- local.
Common situations: A developer prototyped Codex hooks in the checkout and left hooks/hooks.json in place; an upstream branch introduced default hooks while a local-mode workflow is in use; hooks directory restored from an old branch during a rebase.
Related errors
- Local skill mode cannot represent Codex runtime components:
- Cleanup currently supports only the compound-engineering plu
- Unknown cleanup target: ${target}. Use one of: ${cleanupTarg
- Unknown permissions mode: ${permissions}
- Unknown target: ${targetName}
AI-assisted analysis of EveryInc/compound-engineering-plugin@c9c10f8c75 (2026-08-31).
Data as JSON: /api/errors/601ee2859e87ec1a.
Report an issue: GitHub.