balderdashy/sails · error
E_CONFLICT
E_CONFLICT
Error message
The action `' + actionName + '` in `' + filePath + '` conflicts with a previously-loaded action.
What it means
When Sails auto-loads controller modules from api/controllers, it derives each action identity from folder/file/action names lowercased. If a second file on disk yields an identity already loaded (actionsLoadedFromDisk), load fails with E_CONFLICT before the action can be registered.
Source
Thrown at lib/app/private/controller/load-action-modules.js:100
if (_.isString(action)) {return;}
// Give the action name `_config` special treatement: just merge it into the blueprint
// config instead of trying to load it as an action.
if (actionName === '_config') {
if (sails.config.blueprints) {
sails.config.blueprints._controllers[identity.toLowerCase()] = action;
}
return;
}
// The action identity is the controller identity + the action name,
// with path separators transformed to dots.
// e.g. somefolder.somecontroller.dostuff
var actionIdentity = (identity + '/' + actionName).toLowerCase();
// If the action identity matches one we've already loaded from disk, bail.
if (actionsLoadedFromDisk[actionIdentity]) {
throw flaverr({ name: 'userError', code: 'E_CONFLICT', identity: actionIdentity}, new Error('The action `' + actionName + '` in `' + filePath + '` conflicts with a previously-loaded action.'));
}
// Attempt to load the action into our set of actions.
// Since the following code might throw E_CONFLICT errors, we'll inject a `try` block here
// to intercept them and wrap the Error.
try {
helpRegisterAction(sails, action, actionIdentity, true);
} catch (e) {
switch (e.code) {
case 'E_CONFLICT':
// Improve error message with addtl contextual information about where this action came from.
// (plus a slightly better stack trace)
throw flaverr({
name: 'userError', code: 'E_CONFLICT', identity: actionIdentity },
new Error('Failed to register `' + actionName + '`, an action in the controller loaded from `'+filePath+'` because it conflicts with a previously-registered action.')
);
View on GitHub (pinned to 7b76422cc2)
Solutions
- Rename one of the conflicting actions or its file so identities differ.
- Delete duplicate/stale controller files (check subfolders of api/controllers).
- Check identity casing: files differing only in case collide after lowercasing; use distinct names.
- Run with verbose logging to see which filePath collides and remove the redundant one.
Example fix
// before: api/controllers/user.js exports create, api/controllers/user/create.js exists // after: rename the action // api/controllers/user.js exports create // api/controllers/user/create-profile.js exports createProfile
Defensive patterns
Strategy: validation
Validate before calling
// before lift: detect duplicate lowercased controller action identities
var seen = {};
for (const [file, actions] of Object.entries(collectedActions)) {
for (const name of Object.keys(actions)) {
const id = (file + '/' + name).toLowerCase();
if (seen[id]) { throw new Error('duplicate action identity: ' + id); }
seen[id] = file;
}
} Try / catch
try { await sails.lift(); } catch (e) { if (e.code === 'E_CONFLICT' && /conflicts with a previously-loaded action/.test(e.message)) { console.error('Duplicate action on disk:', e.message); process.exit(1); } throw e; } Prevention
- Avoid files differing only in case in api/controllers.
- Do not keep duplicate copies of a controller in subfolders.
- Rename one of two same-named actions across controller files.
- Search the repo for duplicate action export names before lifting.
When it happens
Trigger: Two controller files (including those in api/controllers subfolders) exporting same-named actions whose lowercased `identity/actionname` identities collide, e.g. user.js and user/index.js both exporting `create`.
Common situations: Case-insensitive collisions (Foo.js and foo.js); controller and api/controllers subfolder file defining the same action; copying a controller into a subfolder without deleting the original.
Related errors
- E_CONFLICT
- E_INVALID_HOOK_NAME
- Ignored attempt to bind route (${path}) to unknown action ::
- Cannot call res.render() - `req._sails.renderView` was not a
- The 2-ary usage of `res.redirect()` is no longer supported i
AI-assisted analysis of balderdashy/sails@7b76422cc2 (2026-09-01).
Data as JSON: /api/errors/803e33b8a8d37f25.
Report an issue: GitHub.