balderdashy/sails · warning

Ignoring unexpected `files` property in helper definition lo

Error message

Ignoring unexpected `files` property in helper definition loaded from ${helperDef._loadedFrom}.  This feature can only be used by actions, not by helpers!

What it means

Helpers in Sails cannot use the `files` property (multipart file upload support), which is exclusive to actions. When the helpers hook loads a helper definition that includes `files`, it logs this warning and ignores that property, telling you the file the helper was loaded from and that `files` is actions-only.

Source

Thrown at lib/hooks/helpers/private/load-helpers.js:64

          var keyPath = _.map(identity.split('/'), _.camelCase).join('.');

          // Save _loadedFrom property for debugging purposes.
          // (e.g. `financial/calculate-mortgage-series`)
          helperDef._loadedFrom = identity;

          // Save _fromLocalSailsApp for internal use.
          helperDef._fromLocalSailsApp = true;

          // Use filename-derived `identity` REGARDLESS if an explicit identity
          // was set.  (And exclude any extra hierarchy.)  Otherwise, as of
          // machine@v15, this could fail with an ImplementationError.
          helperDef.identity = identity.match(/\//) ? _.last(identity.split('/')) : identity;

          // Check helper def to make sure it doesn't include any obvious signs
          // of confusion with actions -- e.g. no "responseType".  If anything
          // like that is detected, log a warning.
          if (helperDef.files) {
            sails.log.warn(
              'Ignoring unexpected `files` property in helper definition loaded '+
              'from '+helperDef._loadedFrom+'.  This feature can only be used '+
              'by actions, not by helpers!'
            );
          }
          var hasAnyConfusingExitProps = (
            _.isObject(helperDef.exits) &&
            _.any(helperDef.exits, function(exitDef){
              return (
                _.isObject(exitDef) &&
                (
                  exitDef.responseType !== undefined ||
                  exitDef.viewTemplatePath !== undefined ||
                  exitDef.statusCode !== undefined
                )
              );
            })
          );

View on GitHub (pinned to 7b76422cc2)

Solutions

  1. Remove the `files` property from the helper definition.
  2. Perform file uploads in an action (actions2 with `files`), then pass file metadata/contents into the helper as normal inputs.
  3. Rename/restructure the helper back into an action if upload handling is its core purpose.

Example fix

// before (api/helpers/upload-avatar.js)
module.exports = { files: ['avatar'], fn: async (inputs) => {...} };
// after
module.exports = { fn: async ({ avatar }) => {...} }; // handle req.file(...) in the action, pass the upload here
Defensive patterns

Strategy: validation

Validate before calling

if (helperDef.files !== undefined) console.warn('`files` is only valid in actions; remove it from helper ' + identity);

Prevention

When it happens

Trigger: A helper in api/helpers defines `files: [...]` (or similar) in its fnInputs/def, detected while load-helpers.js inspects each loaded helper definition.

Common situations: Copy-pasting an action into a helper (including its `files` option), refactoring an upload action into a helper expecting uploads to still work, or scaffolding tools that carried the property over.

Related errors


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