expressjs/express · error · TypeError

path must be a string to res.sendFile

Error message

path must be a string to res.sendFile

What it means

Thrown by `res.sendFile` when a truthy `path` argument is not a string (e.g. a Buffer, number, array, or object). The path is later passed to `encodeURI` and the `send` module, both of which require a string, so Express rejects other types up front.

Source

Thrown at lib/response.js:385

 *       });
 *     });
 *
 * @public
 */

res.sendFile = function sendFile(path, options, callback) {
  var done = callback;
  var req = this.req;
  var res = this;
  var next = req.next;
  var opts = options || {};

  if (!path) {
    throw new TypeError('path argument is required to res.sendFile');
  }

  if (typeof path !== 'string') {
    throw new TypeError('path must be a string to res.sendFile')
  }

  // support function as second arg
  if (typeof options === 'function') {
    done = options;
    opts = {};
  }

  if (!opts.root && !pathIsAbsolute(path)) {
    throw new TypeError('path must be absolute or specify root to res.sendFile');
  }

  // create file stream
  var pathname = encodeURI(path);

  // wire application etag option to send
  opts.etag = this.app.enabled('etag');
  var file = send(req, pathname, opts);

View on GitHub ↗ (pinned to a3714473fe)

Solutions

  1. Pass the filesystem path string, not the file's contents or an object: `res.sendFile('/abs/path/file.txt')`.
  2. If using a URL or Path-like object, convert it first (e.g. `fileURLToPath(url)` or `String(p)`).
  3. If the value comes from req.query, reject non-string values (repeat params arrive as arrays).

Example fix

// before
res.sendFile(fs.readFileSync(filePath));
// after
res.sendFile(filePath); // sendFile reads the file itself
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof filePath !== 'string') {
  return next(new TypeError('resolved file path is not a string'));
}
res.sendFile(filePath, { root: PUBLIC_DIR });

Type guard

function isPathString(p) {
  return typeof p === 'string' && p.length > 0;
}

Prevention

When it happens

Trigger: `res.sendFile(fs.readFileSync(p))` (passing file contents instead of the path), `res.sendFile(['a.txt'])`, `res.sendFile({ path: p })`, or passing a URL/Path object instead of a string.

Common situations: Confusing sendFile (takes a path) with res.send (takes a body); passing a `URL` or `path`-like object from a library; array-valued query params (`?file=a&file=b`) producing an array from req.query.

Related errors


AI-assisted analysis of expressjs/express@a3714473fe (2026-07-31). Data as JSON: /data/errors/63fd865fb5001160.json. Report an issue: GitHub ↗.