{"record":{"id":"803e33b8a8d37f25","repo":"balderdashy/sails","slug":"e-conflict-803e33","errorCode":"E_CONFLICT","errorMessage":"The action `' + actionName + '` in `' + filePath + '` conflicts with a previously-loaded action.","messagePattern":"The action `' \\+ actionName \\+ '` in `' \\+ filePath \\+ '` conflicts with a previously-loaded action\\.","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/app/private/controller/load-action-modules.js","lineNumber":100,"sourceCode":"            if (_.isString(action)) {return;}\n\n            // Give the action name `_config` special treatement: just merge it into the blueprint\n            // config instead of trying to load it as an action.\n            if (actionName === '_config') {\n              if (sails.config.blueprints) {\n                sails.config.blueprints._controllers[identity.toLowerCase()] = action;\n              }\n              return;\n            }\n\n            // The action identity is the controller identity + the action name,\n            // with path separators transformed to dots.\n            // e.g. somefolder.somecontroller.dostuff\n            var actionIdentity = (identity + '/' + actionName).toLowerCase();\n\n            // If the action identity matches one we've already loaded from disk, bail.\n            if (actionsLoadedFromDisk[actionIdentity]) {\n              throw flaverr({ name: 'userError', code: 'E_CONFLICT', identity: actionIdentity}, new Error('The action `' + actionName + '` in `' + filePath + '` conflicts with a previously-loaded action.'));\n            }\n\n            // Attempt to load the action into our set of actions.\n            // Since the following code might throw E_CONFLICT errors, we'll inject a `try` block here\n            // to intercept them and wrap the Error.\n            try {\n              helpRegisterAction(sails, action, actionIdentity, true);\n            } catch (e) {\n              switch (e.code) {\n\n                case 'E_CONFLICT':\n                  // Improve error message with addtl contextual information about where this action came from.\n                  // (plus a slightly better stack trace)\n                  throw flaverr({\n                    name: 'userError', code: 'E_CONFLICT', identity: actionIdentity },\n                    new Error('Failed to register `' + actionName + '`, an action in the controller loaded from `'+filePath+'` because it conflicts with a previously-registered action.')\n                  );\n","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/balderdashy/sails/blob/7b76422cc27823df033572bdda5c4910a68b697f/lib/app/private/controller/load-action-modules.js#L82-L118","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","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."],"exampleFix":"// before: api/controllers/user.js exports create, api/controllers/user/create.js exists\n// after: rename the action\n// api/controllers/user.js exports create\n// api/controllers/user/create-profile.js exports createProfile","handlingStrategy":"validation","validationCode":"// before lift: detect duplicate lowercased controller action identities\nvar seen = {};\nfor (const [file, actions] of Object.entries(collectedActions)) {\n  for (const name of Object.keys(actions)) {\n    const id = (file + '/' + name).toLowerCase();\n    if (seen[id]) { throw new Error('duplicate action identity: ' + id); }\n    seen[id] = file;\n  }\n}","typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["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."],"tags":["sails","controllers","conflict","autoload","duplicate"],"backgroundTag":"action-identity-conflict","analyzedSha":"7b76422cc27823df033572bdda5c4910a68b697f","analyzedAt":"2026-09-01T04:01:57.104Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}