balderdashy/sails · error

Cannot write to response more than once

Error message

Cannot write to response more than once

What it means

Sails virtual responses (res.view, res.json, res.send, etc.) guard against writing to the underlying HTTP response twice. `onlyAllowOneResponse` throws this error if a second response method is invoked after a previous one already started writing, because the Node/Express response stream can only be ended once.

Source

Thrown at lib/router/res.js:423



  return res;


};


/**
 * NOTE: ALL RESPONSES (INCLUDING REDIRECTS) ARE PREVENTED ONCE THE RESPONSE HAS BEEN SENT!!
 * Even though this is not strictly required with sockets, since res.redirect()
 * is an HTTP-oriented method from Express, it's important to maintain consistency.
 *
 * @api private
 */
function onlyAllowOneResponse (res) {
  if (res._virtualResponseStarted) {
    throw new Error('Cannot write to response more than once');
  }
  res._virtualResponseStarted = true;
}


// The constructor for clientRes stream
// (just a normal transform stream)
function MockClientResponse() {
  Transform.call(this);
}
util.inherits(MockClientResponse, Transform);
MockClientResponse.prototype._transform = function(chunk, encoding, next) {
  this.push(chunk);
  next();
};

View on GitHub (pinned to 7b76422cc2)

Solutions

  1. Add `return` before the first response call (e.g. `return res.json(...)`) so execution stops after responding.
  2. Audit the handler/policies chain for code paths that can both respond.
  3. If responding in async callbacks, check `res.headersSent`/flow so only one path responds.
  4. Move fallback responses into .catch blocks that are skipped on success.

Example fix

// before
res.json({ ok: true });
res.view('pages/home');
// after
return res.json({ ok: true });
Defensive patterns

Strategy: try-catch

Validate before calling

if (res.headersSent || res._virtualResponseStarted) { return; } // before issuing another response

Type guard

function canRespond(res) { return !res.headersSent && !res._virtualResponseStarted; }

Try / catch

try { return res.json(data); } catch (e) { if (e.message === 'Cannot write to response more than once') { sails.log.warn('double response in handler'); return; } throw e; }

Prevention

When it happens

Trigger: Calling two response methods in one request handler, e.g. `res.json(...)` followed by `res.view(...)` or `res.redirect(...)` after a body was already sent; missing `return` after the first response call in an async branch; calling res.* again after res.ok/res.serverError.

Common situations: Forgetting `return res.json(...)` so the next line also responds; responding both in a promise .then and .catch; double-responding when a policy/handler already sent a response.

Related errors


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