affaan-m/ECC · error
Invalid : expected at least one hook event
Error message
Invalid ${label}: expected at least one hook event What it means
A managed hooks config must contain at least one hook event key. validateManagedHooks throws this error when the config is a plain object but has zero keys ({}), because installing an empty hook set via this API is treated as a mistake rather than a no-op.
Solutions
- Provide at least one hook event in the object, e.g. {"SessionStart":[{type:'command', command:'...'}]}.
- If you intend to remove all hooks, use the API's removal/uninstall path rather than validating an empty desired set.
- Fix upstream filters so they do not silently drop every hook; log when the filtered set is empty.
- Generate hooks before validation, or short-circuit the install call when the hook list is empty.
Example fix
// before
validateManagedHooks({});
// after
const hooks = { "SessionStart": [{ "type": "command", "command": "node hooks/session-start.js" }] };
validateManagedHooks(hooks); Defensive patterns
Strategy: validation
Validate before calling
if (Object.keys(desiredHooks).length === 0) { throw new Error('Refusing to install an empty managed hooks set — use the uninstall API or fix the filter'); } Type guard
const nonEmptyHooks = (v) => v !== null && typeof v === 'object' && Object.keys(v).length > 0;
Try / catch
try { installHooks(desired); } catch (e) { if (e.message.includes('expected at least one hook event')) { console.error('Desired hooks resolved to empty — check filters/generators:', e.message); process.exitCode = 1; } else throw e; } Prevention
- Log when a filter reduces the hook set to zero.
- Use the dedicated removal path for deleting all hooks.
- Generate at least one hook event before install.
When it happens
Trigger: Calling materializeManagedHooks/validateManagedHooks with {} or an object whose keys were all filtered out; computing a diff where all hooks were removed and passing the resulting empty object as the desired set.
Common situations: A filter step (by event, by agent) removed every hook before install; a fresh project generating hooks from an empty list; migrating configs where the source hooks block was empty; conditional code that builds hooks but skips adding any.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Invalid hook entry at
- Invalid hooks config: expected a JSON object with a hooks…
- Invalid . : expected a non-empty hook array
- Invalid managed hook handler at
- Invalid managed hook handler at
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/d5b169bc70cef3d6.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/install/claude-settings.js:132
) {
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`);
}
if (entries.length === 0) {
throw new Error(`Invalid ${label}.${event}: expected at least one hook entry`);
}
entries.forEach((entry, index) => {
if (!isJsonObject(entry)) {
throw new Error(
`Invalid managed hook entry at ${label}.${event}[${index}]: expected a JSON object`View on GitHub (pinned to 8321021c54)