balderdashy/sails · warning

Files in the `controllers` directory may be traditional cont

Error message

Files in the `controllers` directory may be traditional controllers or 
action files.  Traditional controllers are dictionaries of actions, with 
pascal-cased filenames ending in "Controller" (e.g. MyGreatController.js).
Action files are kebab-cased (e.g. do-stuff.js) and contain a single action.
The following file${garbage.length > 1 ? 's were' : ' was'} ignored for not meeting those criteria:

What it means

When loading action modules from api/controllers, Sails classifies each file as either a traditional controller (pascal-cased name ending in 'Controller', exporting a dictionary of actions) or an action file (kebab-cased, exporting a single action). Files matching neither convention are 'garbage': they are ignored, and this warning lists the naming rules and the offending files.

Source

Thrown at lib/app/private/controller/load-action-modules.js:180

          // Flag that an action with the given identity was successfully loaded from disk.
          actionsLoadedFromDisk[actionIdentity] = true;

        } // </ is it an action?>

        // Otherwise give up on this file, it's GARBAGE.
        // No, no, it's probably a very nice file but it's
        // no controller as far as we're concerned.
        else {
          garbage.push(filePath);
        } // </ it is garbage>

      }); // </each(file from includeAll)>


      // Complain about garbage.
      if (garbage.length) {
        sails.log.warn('---------------------------------------------------------------------------');
        sails.log.warn('Files in the `controllers` directory may be traditional controllers or \n' +
                     'action files.  Traditional controllers are dictionaries of actions, with \n' +
                     'pascal-cased filenames ending in "Controller" (e.g. MyGreatController.js).\n' +
                     'Action files are kebab-cased (e.g. do-stuff.js) and contain a single action.\n'+
                     'The following file'+(garbage.length > 1 ? 's were' : ' was')+' ignored for not meeting those criteria:');
        _.each(garbage, function(filePath){sails.log.warn('- '+filePath);});
        sails.log.warn('----------------------------------------------------------------------------\n');
      }

      // (Shallow) merge stuff from sails.config.controllers.moduleDefinitions on top of any loaded files.
      // Note that the third argument (force) to `helpRegisterAction` is `true`, so there's no danger
      // of identity conflicts.  Actions defined in `moduleDefinitions` will override anything else.
      _.each(_.get(sails, 'config.controllers.moduleDefinitions') || {}, function(action, actionIdentity) {
        helpRegisterAction(sails, action, actionIdentity, true);
      });

    } catch (e) { return cb(e); }

    // Get a list of the action identities.

View on GitHub (pinned to 7b76422cc2)

Solutions

  1. Rename the listed files to kebab-case (do-stuff.js) if they are single actions.
  2. Rename to pascal-case ending in Controller (UserController.js) if they are traditional controllers.
  3. Move non-action utility files out of api/controllers into api/services or a lib/ folder.

Example fix

// before
api/controllers/user_helpers.js      // ignored, warned
// after
api/controllers/user-helpers.js      // valid action file (or move to api/services/)
Defensive patterns

Strategy: validation

Validate before calling

const files = fs.readdirSync('api/controllers');
const bad = files.filter(f => !/^[A-Z][A-Za-z0-9]*Controller\.js$/.test(f) && !/^[a-z0-9]+(-[a-z0-9]+)*\.js$/.test(f));
if (bad.length) console.warn('Non-conforming controller files:', bad);

Prevention

When it happens

Trigger: api/controllers contains files whose names are neither PascalCase ending in Controller.js nor kebab-case .js action files — e.g. camelCase.js, snake_case.js, 'My Controller.js', or non-.js files picked up by includeAll.

Common situations: Utility/helper files stashed in api/controllers, files named with spaces or underscores, leftover backups like oldController.js.bak, or generated code that used the wrong casing convention.

Related errors


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