{"record":{"id":"044980fe7888e96b","repo":"balderdashy/sails","slug":"warning-route-address-should-explicitly-decl","errorCode":null,"errorMessage":"Warning: route `${address}` should explicitly declare `skipAssets: true` or `skipAssets: false` to ensure correct handling of assets!","messagePattern":"Warning: route `(.+?)` should explicitly declare `skipAssets: true` or `skipAssets: false` to ensure correct handling of assets!","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"lib/router/index.js","lineNumber":377,"sourceCode":"\n  // Updated the sorted route address cache\n  sortedRouteAddresses = sortRouteAddresses(_.keys(this.explicitRoutes));\n\n  // Iterate over each address and bind the route that the address is for.\n  _.each(sortedRouteAddresses, function(address) {\n    var target = self.explicitRoutes[address];\n    var verb = detectVerb(address).verb;\n\n    // If the route address ends in a pattern var (e.g. /:id) or a wildcard (i.e. /*)\n    // and it declares a method that could be used to request an asset, and the route\n    // doesn't explicitly declare `skipAssets` true or false, then it should!\n    var shouldDeclareSkipAssets = (\n      _.isUndefined(target.skipAssets) &&\n      (address.match(/\\/\\*\\/?$/) || address.match(/^r\\|/)) &&\n      (!verb || _.contains(['all', 'get', 'head', 'options'], verb))\n    );\n    if (shouldDeclareSkipAssets) {\n      sails.log.warn('Warning: route `' + address + '` should explicitly declare `skipAssets: true` or `skipAssets: false` to ensure correct handling of assets!');\n      sails.log.warn('See http://sailsjs.com/docs/concepts/routes/url-slugs for more info.');\n      console.log();\n    }\n\n    self.bind(address, target);\n  });\n\n  // Fired after static routes are bound\n  sails.emit('router:after');\n};\n\n\n/**\n * Given a route target configuration, return an action identity for that target.\n * @param  {Dictionary|String} target The route target to get an action identity for\n * @return {String}        An action identity like `user/find`\n */\nRouter.prototype.getActionIdentityForTarget = function getActionIdentityForTarget(target) {","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/balderdashy/sails/blob/7b76422cc27823df033572bdda5c4910a68b697f/lib/router/index.js#L359-L395","documentation":"For catch-all style routes (ending in `/*` or `/?`, or regex-syntax `r|...` routes) bound with permissive verbs (all/get/head/options) where the target omits `skipAssets`, Sails warns because static asset requests (images, js, css) may accidentally match the route. Explicitly declaring `skipAssets: true` or `false` makes intent clear.","triggerScenarios":"Binding e.g. `'GET /*': 'PageController.show'` or any `/*`-style route without a `skipAssets` property in the target object.","commonSituations":"Catch-all routing for SPAs or CMS-style pages; developers forget that without skipAssets the route will also swallow requests for static files.","solutions":["Add `skipAssets: true` to the route target so it ignores static asset URLs","Add `skipAssets: false` explicitly if you truly want the route to handle asset paths","Scope the catch-all pattern more narrowly (e.g. `/page/*`) to avoid the ambiguity"],"exampleFix":"// before\n'GET /*': 'PageController.show'\n// after\n'GET /*': { view: 'homepage', skipAssets: true }","handlingStrategy":"validation","validationCode":"function assertSkipAssets(routes) {\n  for (const [addr, target] of Object.entries(routes)) {\n    if (/\\*\\/?$/.test(addr) && target && target.skipAssets === undefined) {\n      console.warn(`Route ${addr} should declare skipAssets: true|false`);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set skipAssets explicitly on wildcard routes","Scope catch-alls narrowly instead of using bare /*","Review the URL-slugs docs when designing route tables"],"tags":["routing","assets","config","sails"],"backgroundTag":"ambiguous-catch-all-route","analyzedSha":"7b76422cc27823df033572bdda5c4910a68b697f","analyzedAt":"2026-09-01T04:01:57.104Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}