Kuberwastaken/claurst · error · anyhow::Error

unsupported hooks event

Error message

unsupported hooks event: {name}

What it means

parse_hook_event maps hook event key names to HookEvent variants and only accepts the known set: PreToolUse, PostToolUse, Stop, PostModelTurn, UserPromptSubmit, Notification. Any other key inside the hooks object produces this error and the import aborts.

Solutions

  1. Rename the unsupported event key to one of the supported events (PreToolUse, PostToolUse, Stop, PostModelTurn, UserPromptSubmit, Notification)
  2. Remove the unsupported event entry before importing (or downgrade the source config to supported events)
  3. Fix casing — event names are matched exactly and are case-sensitive

Example fix

// before
{ "hooks": { "SubagentStop": [ { "hooks": [ { "command": "cleanup.sh" } ] } ] } }
// after
{ "hooks": { "Stop": [ { "hooks": [ { "command": "cleanup.sh" } ] } ] } }
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = ['PreToolUse','PostToolUse','Stop','PostModelTurn','UserPromptSubmit','Notification'];
for (const ev of Object.keys(cfg.hooks ?? {})) if (!SUPPORTED.includes(ev)) throw new Error(`unsupported hooks event: ${ev}`);

Type guard

const isSupportedEvent = (ev) => ['PreToolUse','PostToolUse','Stop','PostModelTurn','UserPromptSubmit','Notification'].includes(ev);

Try / catch

try { importConfig(path) } catch (e) { const m = String(e).match(/unsupported hooks event: (\S+)/); if (m) { dropOrRemapEvent(path, m[1]); } else { throw e; } }

Prevention

When it happens

Trigger: Importing hooks keyed by an event name outside the supported set, e.g. "SessionStart", "SubagentStop", "PreCompact", or lowercase/case-mismatched names like "pretooluse".

Common situations: Config written for a newer version of Claude Code with additional hook events, custom event names, or typos/case errors in event keys.

Related errors


AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10). Data as JSON: /api/errors/17a57874de065e88. Report an issue: GitHub.

Appendix: source

Thrown at src-rust/crates/core/src/import_config.rs:759

                    tool_filter: if matcher == "*" { None } else { Some(matcher.clone()) },
                    blocking: false,
                });
            }
        }
        out.insert(event, hook_entries);
    }
    Ok(out)
}

fn parse_hook_event(name: &str) -> Result<HookEvent> {
    match name {
        "PreToolUse" => Ok(HookEvent::PreToolUse),
        "PostToolUse" => Ok(HookEvent::PostToolUse),
        "Stop" => Ok(HookEvent::Stop),
        "PostModelTurn" => Ok(HookEvent::PostModelTurn),
        "UserPromptSubmit" => Ok(HookEvent::UserPromptSubmit),
        "Notification" => Ok(HookEvent::Notification),
        _ => Err(anyhow!("unsupported hooks event: {name}")),
    }
}

fn skip_reason_for_key(key: &str) -> &'static str {
    match key {
        "env" => "contains sensitive environment variables and is not imported automatically",
        "ANTHROPIC_AUTH_TOKEN" | "apiKey" | "providers" => "auth and provider credentials are not migrated automatically",
        "enabledPlugins" => "plugin config structure differs from the current program",
        "disabledMcpServers" => "the current program has no matching field",
        "extraKnownMarketplaces" => "the current program has no matching field",
        "skipAutoPermissionPrompt" => "the current program has no matching field",
        "autoDreamEnabled" => "the current program has no matching field",
        "codemossProviderId" => "the current program has no matching field",
        "effortLevel" => "the current program has no stable persistence mapping",
        _ => "the current program does not support this field",
    }
}

View on GitHub (pinned to b0637c97ec)