balderdashy/sails · warning · Error
E_INVALID_HOOK_NAME
E_INVALID_HOOK_NAME
Error message
Found hook: `HOOK_NAME`, in `node_modules/`, but a hook with that identity already exists in `api/hooks/`. The hook defined in your `api/hooks/` folder will take precedence.
What it means
E_INVALID_HOOK_NAME warning from the moduleloader: a hook was found in node_modules/ whose identity collides with a hook already defined in the app's api/hooks/ folder. It is not fatal — Sails logs a warning and the api/hooks/ version takes precedence; the node_modules hook is skipped.
Source
Thrown at lib/hooks/moduleloader/index.js:551
return memo;
}
// Allow overriding core hooks
if (sails.hooks[hookName]) {
sails.log.verbose('Found hook: `'+hookName+'` in `node_modules/`. Overriding core hook w/ the same identity...');
}
// If we have a hook in api/hooks with this name, throw an error
if (hooks[hookName]) {
var err = (function (){
var msg =
'Found hook: `' + hookName + '`, in `node_modules/`, but a hook with that identity already exists in `api/hooks/`. '+
'The hook defined in your `api/hooks/` folder will take precedence.';
var err = new Error(msg);
err.code = 'E_INVALID_HOOK_NAME';
return err;
})();
sails.log.warn(err);
return memo;
}
// Load the hook code
var hook = require(path.resolve(sails.config.appPath, 'node_modules', identity));
// Set its config key (defaults to the hook name)
hook.configKey = (sails.config.installedHooks && sails.config.installedHooks[identity] && sails.config.installedHooks[identity].configKey) || hookName;
// Add this to the list of hooks to load
memo[hookName] = hook;
return memo;
}, {}));//</_.reduce() + _.extend()>
return bindToSails(cb)(null, hooks);
} catch (e) { return cb(e); }View on GitHub (pinned to 7b76422cc2)
Solutions
- Remove one of the duplicate hooks (delete api/hooks/<name> or uninstall the node_modules package).
- If the api/hooks/ version is intended, ignore the warning or uninstall the npm duplicate.
- Rename one of the hooks so identities differ.
- Confirm which copy is actually loading via sails.hooks to avoid stale-behavior confusion.
Example fix
// before: both api/hooks/auth/ and node_modules/auth exist // after npm uninstall auth # keep the api/hooks/auth copy in control
Defensive patterns
Strategy: validation
Validate before calling
const fs = require('fs'), path = require('path');
const custom = fs.existsSync(path.join('api/hooks', hookName));
const inNm = fs.existsSync(path.join('node_modules', hookName));
if (custom && inNm) console.warn('Duplicate hook identity: ' + hookName); Type guard
function isHookNameCollision(names) { const set = new Set(names); return names.length !== set.size ? [...set] : null; } Prevention
- When npm-ifying a custom hook, delete the api/hooks copy.
- Compare api/hooks/ dir names with sails.config.hookOverrides/installed packages.
- Inspect sails.hooks after lift to confirm which copy loaded.
When it happens
Trigger: Installing an npm package whose name matches a custom hook in api/hooks/ (e.g. api/hooks/myhook and node_modules/myhook), or scaffolding a custom hook with the same name as an installed sails hook package.
Common situations: Moving a hook from api/hooks/ into an npm package (or vice versa) and leaving both copies; installing a package that coincidentally shares a hook identity.
Related errors
- E_CONFLICT
- Cannot call res.render() - `req._sails.renderView` was not a
- The 2-ary usage of `res.redirect()` is no longer supported i
- Cannot write to response more than once
- rc(name): name *must* be string
AI-assisted analysis of balderdashy/sails@7b76422cc2 (2026-09-01).
Data as JSON: /api/errors/393af30bd50808d4.
Report an issue: GitHub.