affaan-m/ECC · error
Invalid managed hook handler at
Error message
Invalid managed hook handler at ${label}: invalid model What it means
For prompt-type hooks, the optional 'model' field must be a non-empty string naming the model to use. validateHookHandler throws this error when hook.model is present but is not a non-empty string (empty, blank, number, object, array, or null).
Solutions
- Set model to a non-empty string model id, e.g. model:'sonnet'.
- Remove the model field to use the default model.
- Quote model ids in YAML so they stay strings.
- Ensure env-placeholder substitution for model names actually resolves.
Example fix
// before
{ "type": "prompt", "prompt": "Review", "model": 4.5 }
// after
{ "type": "prompt", "prompt": "Review", "model": "sonnet" } Defensive patterns
Strategy: validation
Validate before calling
const bad = hooks.filter(h=>h.model!==undefined&&!(typeof h.model==='string'&&h.model.trim()!=='')); if (bad.length) throw new Error('model must be a non-empty string'); Type guard
const hasValidModel = (h) => h.model === undefined || (typeof h.model === 'string' && h.model.trim() !== '');
Try / catch
try { installHooks(cfg); } catch (e) { if (e.message.includes('invalid model')) { console.error('Hook model must be a non-empty string:', e.message); process.exitCode = 1; } else throw e; } Prevention
- Quote model ids in YAML.
- Delete model field to accept the default.
- Reject numeric model values at config-load time.
When it happens
Trigger: validateManagedHooks encounters {type:'prompt', prompt:'x', model:''}, model:' ', model:3.5, model:{name:'haiku'}, or model:null.
Common situations: Model specified as a number ('sonnet 4.5' parsed as 4.5); empty model after stripping an env placeholder; nesting the model under an object; YAML unquoted model ids that parsed as non-strings.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Invalid : expected a JSON object
- Invalid managed hook handler at
- Invalid managed hook handler at
- application config exceeds local size limit
- Asset request_id/modality does not match the bundle
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/bcbc9758761820e1.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/install/claude-settings.js:123
&& (!isJsonObject(hook.headers)
|| !Object.values(hook.headers).every(value => typeof value === 'string'))
) {
throw new Error(`Invalid managed hook handler at ${label}: invalid headers`);
}
if (
hook.allowedEnvVars !== undefined
&& (!Array.isArray(hook.allowedEnvVars)
|| !hook.allowedEnvVars.every(isNonEmptyString))
) {
throw new Error(`Invalid managed hook handler at ${label}: invalid allowedEnvVars`);
}
return;
}
if (!isNonEmptyString(hook.prompt)) {
throw new Error(`Invalid managed hook handler at ${label}: invalid prompt`);
}
if (hook.model !== undefined && !isNonEmptyString(hook.model)) {
throw new Error(`Invalid managed hook handler at ${label}: invalid model`);
}
}
function validateManagedHooks(managedHooks, label = 'managed hooks') {
if (!isJsonObject(managedHooks)) {
throw new Error(`Invalid ${label}: expected a JSON object`);
}
if (Object.keys(managedHooks).length === 0) {
throw new Error(`Invalid ${label}: expected at least one hook event`);
}
const seenIds = new Set();
for (const [event, entries] of Object.entries(managedHooks)) {
if (!VALID_EVENTS.has(event)) {
throw new Error(`Invalid ${label}: unsupported hook event "${event}"`);
}
if (!Array.isArray(entries)) {
throw new Error(`Invalid ${label}.${event}: expected an array`);View on GitHub (pinned to 8321021c54)