affaan-m/ECC · error
Invalid managed hook handler at
Error message
Invalid managed hook handler at ${label}: unsupported type What it means
validateHookHandler requires each handler's 'type' field to be one of the VALID_HOOK_TYPES supported by ECC's managed hooks. An object handler with a missing or unrecognized type (e.g. 'script', 'shell', or undefined) is rejected so the installer never writes hook entries Claude cannot interpret.
Solutions
- Set the handler's 'type' to a supported value (e.g. "command") at the labeled location.
- Check VALID_HOOK_TYPES in scripts/lib/install/claude-settings.js for the exact accepted set.
- Update ECC if your hooks schema is newer than the installed version's validator.
Example fix
// before
{ "type": "shell", "command": "node my-hook.js" }
// after
{ "type": "command", "command": "node my-hook.js" } Defensive patterns
Strategy: validation
Validate before calling
import { VALID_HOOK_TYPES } from './scripts/lib/install/claude-settings.js';
for (const handlers of Object.values(settings.hooks ?? {})) {
for (const h of handlers) {
if (!VALID_HOOK_TYPES.has(h.type)) throw new Error(`unsupported hook type: ${h.type}`);
}
} Type guard
const hasValidHookType = (h, valid) => typeof h?.type === 'string' && valid.has(h.type);
Try / catch
try {
validateManagedHooks(hooks);
} catch (e) {
if (e.message.includes('unsupported type')) {
console.error('Use one of:', [...VALID_HOOK_TYPES].join(', '));
} else throw e;
} Prevention
- Check VALID_HOOK_TYPES in scripts/lib/install/claude-settings.js before authoring handlers.
- Keep ECC updated if the Claude hooks schema changed upstream.
- Don't invent hook types; only "command"-style types supported by the validator.
When it happens
Trigger: validateManagedHooks processes a handler object whose hook.type is not in VALID_HOOK_TYPES — missing type field, typo'd type, or a type from a newer/older Claude hooks schema.
Common situations: Copying hook examples from docs for other tools that use different type names; editing type by hand; schema drift after a Claude Code hooks format change.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid Claude hooks preference
- Invalid managed hook handler at
- Invalid managed hook handler at
- -32602
- artifact path must be a non-empty relative path
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/20ecfcfe0b4e7677.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/install/claude-settings.js:76
function assertClaudeSettingsPath(destinationPath, trustedRoot) {
const resolvedDestination = path.resolve(destinationPath);
const resolvedExpected = path.resolve(getClaudeSettingsPath(trustedRoot));
const pathsMatch = process.platform === 'win32'
? resolvedDestination.toLowerCase() === resolvedExpected.toLowerCase()
: resolvedDestination === resolvedExpected;
if (!pathsMatch) {
throw new Error(
`Refusing to manage Claude hooks outside the canonical settings file: ${destinationPath}`
);
}
}
function validateHookHandler(hook, label) {
if (!isJsonObject(hook)) {
throw new Error(`Invalid managed hook handler at ${label}: expected a JSON object`);
}
if (!VALID_HOOK_TYPES.has(hook.type)) {
throw new Error(`Invalid managed hook handler at ${label}: unsupported type`);
}
if (hook.timeout !== undefined && (typeof hook.timeout !== 'number' || hook.timeout < 0)) {
throw new Error(`Invalid managed hook handler at ${label}: invalid timeout`);
}
if (hook.type === 'command') {
const validCommand = isNonEmptyString(hook.command)
|| (Array.isArray(hook.command)
&& hook.command.length > 0
&& hook.command.every(isNonEmptyString));
if (!validCommand) {
throw new Error(`Invalid managed hook handler at ${label}: invalid command`);
}
if (hook.async !== undefined && typeof hook.async !== 'boolean') {
throw new Error(`Invalid managed hook handler at ${label}: invalid async flag`);
}
return;
}View on GitHub (pinned to 8321021c54)