Sign in

We’ve been working on making it work better, and making better work of words better, too. Err…

We’re totally inspired by Slack’s release notes, so wanted to try our flipper at it.

Nov 15th, 2016

Assuming there was no fatal error, should the first argument to an asynchronous callback be `undefined` or `null`?

Best practices for passing the first argument to an asynchronous callback

This is the short and sweet version. If you find it helpful, you might want to check out the entire gist.

In your implementation, if you always do one of the following, you’ll be good to go, and you’ll provide a better experience for the people using your thing:

1. Invoke callback with only err => new Error()

Some kind of fatal error occurred– something where I’d normally throw. Except that I’m an asynchronous function. So instead, I do this:

return cb(new Error('Something bad happened!'));

This is like…

Jan 28th, 2016

TL;DR — If you just installed a new version of Node, check your NPM version. If you’re using NPM v3.3.12 (the default for Node 5.5.0), you could run into issues when installing dependencies in your Sails app. Fortunately, NPM fixed this pretty fast, so all you should have to do is upgrade to the latest version of NPM (npm install -g npm@latest) and everything will be hunky dory.

Version 3.0 of NPM (the Node Package Monger) significantly changed the way dependencies are saved in Node apps. Previously, your project’s node_modules/ folder contained a deeply nested tree of…

Dec 22nd, 2015

1. Recursive invocation (and maximum call stack protection)

just added support for maxRecursion in the machine runner. It’s a top-level property that lets you configure the built-in maximum call stack protection now included in the machine runner (defaults to 250.)

Only works for recursion invoked via env.thisMachine(). For example:

var result = env.thisMachine({ stuff: inputs.i+1 }).execSync();
// ...


env.thisMachine({ stuff: inputs.i+1 }).exec({
error: exits.error,
success: function (result) {
// ...

If maxRecursion is exceeded, instead of returning the real machine instance, env.thisMachine() returns a decoy machine that always triggers its error exit with an Error instance (whose code property is “E_MAX_RECURSION”)

2. Auto-timeout


Oct 20th, 2016

The Node Security project just released an advisory about the CORS implementation in Sails.

tldr; If you are using CORS in your Sails app, review your configuration to be sure it is secure.

If your app has vulnerable CORS configuration, there are two ways to resolve it:

  1. Either replace origin: '*' with a specific set of whitelisted domains
  2. Or set credentials: false

See Concepts > Security > CORS in the Sails docs for more information on how CORS works, and how to use it.

Note that you don’t necessarily need to upgrade to v0.12.7 — although if…

Sep 22nd, 2016

Just reached the next milestone on the road towards Sails v1: As of today, you can add a line of code to your HTML to directly expose data from your server-side view locals to client-side JavaScript, with built-in XSS attack prevention. This eliminates the need to hand-roll your own decoding/encoding (or worse, forget). And it means you don’t need to send a bunch of extra AJAX requests to safely get the data you need onto the web page. …

Aug 1st, 2016

This is a patch release, so there shouldn’t be any breaking changes. The release notes are included below for reference, and to point out what’s changed and what’s new. Big thanks to all of the folks who helped with this release, especially those of you who contributed to testing and documentation!


P.S. If you’re curious what’s next, I posted a first look at the Sails v1.0 roadmap here.

v0.12.4 Release Notes

Originally posted on GitHub

A new patch release with bug fixes, enhancements, and upgrades to Sails’ dependencies.

See also the recently-published improvements to the Sails documentation.



Jun 17th, 2016

The Node Security project released an advisory yesterday about the negotiator package, a dependency of Sails, Express,, and Connect.

tldr; Everything is cool.

Neither Sails nor touches the problematic code paths inside of the negotiatorpackage. And even though the warnings aren’t pertinent in this case, we know they’re still annoying for folks with automated builds, so the core team is working on taking care of them ASAP.

The linked issue from Mike has more information and a blow by blow with an explanation covering each of the places where each of Sails’ dependencies touch negotiator, including:

  • accepts
  • serve-index
  • compression
  • and more

For more details, see:

Apr 1st, 2016

Sails 0.12.2 will be published later today. At the moment, the pre-release is available when you run npm install sails@beta.

If anyone wants to try it out and let us know how it goes, the core team would greatly appreciate it!

The documentation has been updated for the newest release as well, and will be available on as soon as cloudflare allows it. (Until then, you can find the un-cached version here.)

Oh, and in case you were wondering, this is definitely not an April Fool’s prank. That would be the boringest April Fools prank ever.

Jan 12th, 2016

This week, @rachaelshaw and @mikermcneil cleaned up the process for contributing to the Sails docs (removing lots of old branches) and spiffed up the meta-documentation, especially when it comes to versioning and translations. From now on, translation projects will run as forks rather than branches. This will give the maintainers of translation projects more control over contributors and how they merge in upstream documentation changes from the English language documentation.

As far as versioning, there is now a new 0.12 branch, which is used for any changes relating to pull requests, feature proposals, or GitHub issues which…


We make Sails work and things work with Sails.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store