Parents: #495, #473 Regression follow-up to: #693 Related: #682, #686, #692
Problem
The public Zig js.Value.toString(allocator) boundary canonicalizes a primitive String Value, but its non-observable Error-object renderer still reads own name/message fields through Value.asStr() before concatenating them. With flat Latin-1 storage active, an Error carrying caféÿ fields returns physical one-byte storage instead of canonical WTF-8 to the embedder. JavaScript Error.prototype.toString and Error.stack already use representation-aware paths; this is specifically the direct Zig Value rendering API.
Every Promise, stack implementation, queue, job, Worker, and shared Map/Set iterator surface is explicitly excluded and remains user-owned. Error.stack behavior is also out of scope.
Scope
- Canonicalize String-valued Error name/message fields in the Zig-level Value.toString renderer.
- Preserve the renderer’s intentionally side-effect-free own-property behavior, fallback error class name, empty-field formatting, array recursion, existing allocation ownership, and OOM propagation.
- Keep canonical/ASCII fields borrowed; only physical flat Latin-1 performs bounded conversion.
- Add a direct Context-to-public-Value witness that fails with the exact old reads under forced flat storage.
No-workaround rules
- No flat-storage disablement, JavaScript hook invocation, replacement characters, eager global canonicalization, Error.stack change, alternate renderer, hidden retry, or input-specific special case.
- No Promise, stack implementation, queue, job, Worker, or shared Map/Set iterator changes.
Acceptance
- Direct js.Value.toString returns exact canonical WTF-8 for non-ASCII Error name and message fields under canonical and forced-flat storage.
- Empty-name/message and fallback-name rendering remain exact with no observable JavaScript getters invoked.
- Focused Debug, forced-flat Debug, ReleaseSafe, TSan, and full units pass.
- Relevant Test262 accounting is reported without claiming direct Zig API coverage.