Express 5.3 logs Error.cause: keep the Sume request_id

Express 5.3.0 prints the full error object, nested cause included. Wrap a failed Sume call so its code and request_id land in the log line you grep.

4 min readSume
All posts

When an Express 5.3 route fails because a Sume call failed, throw new Error(message, { cause: body.error }) with the parsed Sume error object as the cause. Express 5.3.0, released on 2026-10-09, changed its default error handler to log the whole error object, so the Sume code and request_id print next to the stack without any custom logging.

That matters because the request id is the one thing Sume support asks for. The errors page says the id is safe to share and appears in the response body and headers. If your route turns a 429 into a bare 500, the id is gone by the time anyone reads the log.

What Express 5.3.0 changed

The facts below come from the Express v5.3.0 release notes (read 2026-10-10). Only the first row is about this post; the others are listed so you can judge the upgrade.

Express 5.3.0 release notes, read 2026-10-10
Change in 5.3.0Detail from the notesWhy a Sume caller cares
Default error handler logs the full error objectNested details such as Error.cause are preserved (#6464)A wrapped Sume error shows its code and request_id in the default log
res.send() header fixContent-Length is only added when Transfer-Encoding is absent (#4893, #7459)None for a JSON reply, but read it if you proxy artifacts
Dependency bumpsbody-parser ^2.3.0, qs ^6.16.0, proxy-addr ^2.0.8, with CVE fixes named in the notesUpgrade anyway if the same app receives Sume webhooks

The route

The video docs show POST /v1/videos with model, prompt, and an optional integer duration. The route below submits one job. Express 5 forwards a rejected async handler to the error handler, so there is no try/catch and no next(err).

I ran this file on Express 5.3.0 against a stub that answered 429 with the documented error envelope. The client got a 500, and the default handler wrote the stack plus a [cause] block holding code: 'rate_limited' and the request_id.

import express from "express";

const app = express();
const SUME = process.env.SUME_BASE ?? "https://api.sume.com";

app.post("/render", async (req, res) => {
  const key = req.get("x-render-key"); // one stable key per render request
  if (!key) return res.status(400).json({ error: "x-render-key required" });

  const r = await fetch(`${SUME}/v1/videos`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SUME_API_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": key,
    },
    body: JSON.stringify({ model: "seedance-2.5", prompt: "Rain on a neon street", duration: 5 }),
  });
  const body = await r.json();
  if (!r.ok) {
    // Express 5 forwards a rejected async handler to the error handler.
    throw new Error(`Sume submit failed with ${r.status}`, { cause: body.error });
  }
  res.status(202).json({ job_id: body.id, poll: body.polling_url });
});

app.listen(3000);

What to put in the cause

Put only the parsed error object from the Sume response in cause. It holds code, message, request_id, and details, which are the public fields. Do not put the request headers or the Authorization value in it, because the default handler prints everything you attach.

  • Keep the same Idempotency-Key when you retry the route. Sume's jobs page says a retry with the same key returns the original job instead of billing a second one.
  • A 429 rate_limited carries retry-after when Sume sets it. Read the header before you throw, and put the number in the message if your callers need it.
  • A 402 insufficient_credits is not retryable. Throw it with the cause too, but map it to a different status than a transient 503 so your own clients stop retrying.
  • If you already use a logger such as pino, serialize err.cause yourself. The 5.3.0 change only affects the built-in handler.

This is a logging fix, not a retry policy. The route above still returns a plain 500 for every Sume failure; the improvement is that the next person to open the log can see which Sume error it was.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume