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
- Remove the `files` property from the helper definition.
- Perform file uploads in an action (actions2 with `files`), then pass file metadata/contents into the helper as normal inputs.
- 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
- Never copy the `files` option from an action into a helper.
- Handle req.file(...) uploads in actions and pass results into helpers as inputs.
- Keep helpers side-effect-free with respect to HTTP request/response.
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
- Ignoring unexpected property in one of the exits of the help
- E_INVALID
- Streaming file uploads via `req.file()` are only available o
AI-assisted analysis of balderdashy/sails@7b76422cc2 (2026-09-01).
Data as JSON: /api/errors/c0981369b05ca366.
Report an issue: GitHub.