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
- Add `return` before the first response call (e.g. `return res.json(...)`) so execution stops after responding.
- Audit the handler/policies chain for code paths that can both respond.
- If responding in async callbacks, check `res.headersSent`/flow so only one path responds.
- 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
- Always `return` response calls (return res.json(...)).
- Ensure only one of policy/handler/controller paths sends the response.
- In promise chains, respond in either then or catch, never both.
- Grep handlers for consecutive res.* calls during code review.
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
- Cannot call res.render() - `req._sails.renderView` was not a
- The 2-ary usage of `res.redirect()` is no longer supported i
- rc(name): name *must* be string
- E_INVALID_NODE_ENV
- E_INVALID_ACTION_IDENTITY
AI-assisted analysis of balderdashy/sails@7b76422cc2 (2026-09-01).
Data as JSON: /api/errors/654772ab8819d82c.
Report an issue: GitHub.