balderdashy/sails · error

E_INVALID

E_INVALID

Error message

The action `' + identity + '` could not be registered.  It looks like a machine definition (actions2), but it could not be used to build an action.\nDetails: '+e.stack

What it means

When registerAction receives an object that looks like an actions2 machine definition instead of a function, Sails builds it with machineAsAction. If that construction fails (bad `fn`, invalid `inputs`/`exits`, missing properties), the error is wrapped with code E_INVALID including the underlying machine stack.

Source

Thrown at lib/app/private/controller/help-register-action.js:68

    throw flaverr({ name: 'userError', code: 'E_CONFLICT', identity: identity}, new Error('The action `' + identity + '` could not be registered because it conflicts with a previously-registered action.'));
  }

  // If the action is already a function, hope it's a req/res function
  // and save it in our set of actions.
  if (_.isFunction(action)) {
    actions[identity] = action;

  }
  // Otherwise try to interpret it as an actions2 definition and build a Callable:
  else {

    try {
      actions[identity] = machineAsAction(_.extend({
        implementationSniffingTactic: sails.config.implementationSniffingTactic||undefined,
      }, action));
    }
    catch (e) {
      throw flaverr({ name: 'userError', code: 'E_INVALID', identity: identity, origError: e}, new Error('The action `' + identity + '` could not be registered.  It looks like a machine definition (actions2), but it could not be used to build an action.\nDetails: '+e.stack));
    }
  }

  // Set the _middlewareType, which is used when the log level is "silly" to
  // identify what kind of a thing a route address is bound to.
  actions[identity]._middlewareType = actions[identity]._middlewareType || 'ACTION: ' + identity;

};

View on GitHub (pinned to 7b76422cc2)

Solutions

  1. Read the `Details:` stack in the error to find the actual machine-construction failure.
  2. Ensure the definition has a valid `fn` function and well-formed `inputs`/`exits` objects.
  3. Pass a plain req/res function instead of a machine object if actions2 is not needed.
  4. Check machineAsAction/Machine dependency versions for compatibility with the definition format.

Example fix

// before
sails.registerAction({ name: 'greet' }); // no fn
// after
sails.registerAction({ name: 'greet', fn: async function (inputs, exits) { return exits.success(); } });
Defensive patterns

Strategy: validation

Validate before calling

if (typeof def === 'object' && def !== null) { if (typeof def.fn !== 'function') { throw new Error('actions2 definition for ' + identity + ' needs a fn'); } if (def.inputs && typeof def.inputs !== 'object') { throw new Error('inputs must be an object'); } }

Type guard

function isValidActions2(def) { return def && typeof def === 'object' && typeof def.fn === 'function' && (!def.inputs || typeof def.inputs === 'object') && (!def.exits || typeof def.exits === 'object'); }

Try / catch

try { sails.registerAction(def, identity); } catch (e) { if (e.code === 'E_INVALID') { sails.log.error('Bad actions2 definition for ' + identity + ':\n' + (e.origError && e.origError.stack)); throw e; } throw e; }

Prevention

When it happens

Trigger: Registering an actions2 object whose `fn` is missing/invalid, whose inputs/exits are malformed, or whose implementationSniffingTactic-adjacent fields are wrong, e.g. `sails.registerAction({ name: 'x', inputs: 42 })`-style definitions.

Common situations: Typos in machine definitions (fn key misspelled, wrong nesting); copying actions2 definitions across projects with incompatible machine versions; syntactically valid but semantically invalid inputs/exits.

Related errors


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