2.13.0-beta.20). Features may change before the next stable release.Switch to stable →Troubleshooting
Grok Claude-compat Hook errors
Repair Grok Claude-compat Hook errors without confusing that scanner with AgentKit's native Grok Build spike.
Use this page when Grok reports Hook errors after a Kit was installed for Claude
Code and Grok is scanning Claude settings. It does not describe a native
--target grok install.
Native --target grok is a separate local-source spike. It writes below
.grok, not .claude, and requires --local --kits-dir because no signed
Grok runtime package exists. See Installing kits.
Confirm the symptom
Typical signs on the Claude-compat path:
- Grok shows Hook errors on
SessionStart,UserPromptSubmit,PreToolUse,PostToolUse, orStop. - The failing path is
~/.claude/node, or Node starts without the Hook script. - One-liner Hooks already stored as a single
commandstring still run. Entries with"command": "node"plus anargsarray fail.
Grok reads ~/.claude/settings.json by default in this compatibility mode. It
treats command as a path relative to that JSON file, or as an inline shell
command when the string contains whitespace. It does not use Claude's args
array.
Choose one Hook source
- Claude-compat scanning: the Kit was installed with
--target claude-code, and Grok reads~/.claude/settings.jsonor<project>/.claude/settings.json. Continue with this workaround. - Native Grok projection: the Kit was installed with
--target grokfrom an explicit--local --kits-dirsource. Grok reads AgentKit-managed native files below.grok; do not apply this Claude-settings workaround or add a duplicate overlay.
Do not edit AgentKit-managed settings
Do not rewrite command / args inside ~/.claude/settings.json or
<project>/.claude/settings.json. ak kit update matches managed Hooks by
the .cjs script path and rewrites their managed representation.
Do not create ~/.claude/node as a symlink to your real Node binary. Grok still
drops args, so that shim would start Node with no script.
Do not add a second copy of the same Hooks under ~/.grok/hooks/ while Claude
compat scanning stays on. Grok merges sources and the Hooks would run twice.
Fix the Claude-compat path
Starting with v2.13.0-beta.7, AgentKit folds each managed global Node Hook
into one quoted shell-form command containing the absolute Node runner and
script path, then removes args. Grok can run that form through its Claude
compatibility scanner. Project-native Claude settings keep their portable
node "<script>" form.
Existing global settings are migrated on the next Kit update:
ak kit update engineer --target claude-code --globalUse the Kit name you actually installed. ak kit update replaces prior managed
exec-form entries by their .cjs identity and preserves foreign Hooks. Do not
rewrite the generated commands by hand.
If you previously installed the temporary ~/.grok/hooks/ overlay:
- Keep Claude Hook scanning disabled while the Kit update runs.
- Remove only the AgentKit Hook copies you added under
~/.grok/hooks/. - In
~/.grok/config.toml, set[compat.claude] hooks = true, or delete thehookskey because its default is on. Also stop settingGROK_CLAUDE_HOOKS_ENABLED=0if you used that process-level override. - Start a new Grok session and inspect
/hooks. Project Hooks still need/hooks-trustor--trustbefore they run.
Do not leave the overlay in place after re-enabling Claude Hook scanning. Grok merges both sources, so duplicate Hooks would run twice.
This fix shipped in
agentkit#1609, resolving
agentkit#1607.
ak doctor can confirm a Node runner is still resolvable. Do not treat doctor
output as proof of Grok's stdin schema.
Understand the schema boundary
The Claude-compat fix above repairs command loading only. Grok still sends its
raw camelCase stdin envelope to Hooks discovered through .claude, so a Hook
that expects Claude's snake_case fields can no-op or fail open.
Native --target grok handles exec-form command Hooks differently: AgentKit
emits the owned agentkit-grok-envelope-shim.cjs launcher to add the
Claude-shaped fields, event values, and tool names those Kit scripts expect. It
also restates an applicable PreToolUse exit-2 block as a Grok deny decision.
HTTP handlers and command handlers without exec-form arguments are not wrapped
and still receive Grok's raw envelope.
Native project Hooks remain inactive until you explicitly trust the project.
Timeouts, crashes, malformed output, and shim errors fail open; only an
applicable PreToolUse denial blocks an action. Treat Grok permissions as the
enforcement boundary rather than relying on a Hook alone.