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

  1. Rename one of the conflicting actions or its file so identities differ.
  2. Delete duplicate/stale controller files (check subfolders of api/controllers).
  3. Check identity casing: files differing only in case collide after lowercasing; use distinct names.
  4. 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

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


AI-assisted analysis of balderdashy/sails@7b76422cc2 (2026-09-01). Data as JSON: /api/errors/803e33b8a8d37f25. Report an issue: GitHub.