For Divvent’s own team. It is generated from the operations document in our repository, which is the one to edit. If you use Divvent, the help centre is for you.
6p. A production error, mapped back to source
A tenant's Worker is wrangler's minified bundle, so the stack trace in its logs — or in an incident's evidence — reads _worker.js:1:48213. Every build keeps its source map (decided by Ant, 2026-09-29; docs/proposals/62-build-reply.md): wrangler writes it beside the bundle, the builder Worker asks the container for it once the build's reply is in, and stores it gzipped (about 4 MB) in the control plane's artifacts bucket under the build's hash, at <hash>/.divvent-maps/. It is never in the build's output, never uploaded to the tenant, refused by the deployer's door, and left out of the owner's export, which is the portal's one read of that bucket.
To map one error:
- Find the build. The console's Support page shows each environment's artifact hash in full (the tenant's page shows its first twelve characters). A rolled-back environment runs the hash it was rolled back to — use the one the page shows now, or the one the incident names.
- Find the trace. A tenant's error page shows the person a trace id; the fault record on the console's Logs page carries the same id and no message, by design. The message and its stack are in the tenant Worker's own log (Workers Logs, in the tenant's account), on the line that begins
trace <id>. Put that line and everyat …line under it in a file. - Run it, from a checkout whose
.dev.varsholds the platform account's token (an operator's; no customer has one):
divvent trace <hash> --env production --stack error.txt --why "support ticket 41: 500 on /jobs"
It prints the trace with each frame of the bundle put back to src/…/file.ts:line:column (and the original name in brackets where the map has one). Frames it has no map for, and the message, are left as they were.
Every read is audited, before it happens. artifact.map.read, against the application, naming you (operator:<name>), the build and --why, is written before the first byte is read — so a read that then failed is on the record too. The console's Logs page shows it with the application's other rows. --why is required: a read with no reason is refused before anything is read. Nothing of the map is written to disk; it is inflated in memory and dropped.
When there is no map:
- "has no source maps stored" — the build was made by an image from before 2026-09-29, or its maps did not arrive. The second shows as a
build.mapsfault (SourceMapsMissing) on the console's Logs page, from the hour the build ran: the build passed and deployed, and only its map was lost. Rebuilding that revision does not bring it back — the same inputs are a cache hit — so a trace from that build is read by hand, from the function names (keep_nameskeeps them in the bundle). - "no build of … is registered" — the hash is not a build of this control plane: check
--env.
Retention. A map lives under its build's hash, so it is kept exactly as long as the build is, and goes with it: nothing deletes a build's prefix today (a build is kept while anything could deploy or roll back to it), and whatever does in future takes the map with it. Destroying the control plane empties the bucket, maps included.
What a customer is told. A customer never sees a map or a mapped trace; their application's error page shows a trace id and nothing of the code. When they report an error, ask for that id and roughly when, and map it as above (docs/ERRORS.md is what they are told).