6363 *
6464 * ## Why the issues are re-shaped rather than forwarded verbatim
6565 *
66- * Two measured reasons, not taste:
67- *
68- * - `ObjectLogger` redacts recursively by substring: its default
69- * `redact: ['password', 'token', 'secret', 'key']` matches any field whose
70- * lowercased name *contains* one of them. A Zod `unrecognized_keys` issue
71- * names the offending keys in a field called `keys`, and `'keys'` contains
72- * `'key'` — forwarding `err.issues` untouched therefore renders
73- * `"keys":"***REDACTED***"`, i.e. it loses the one fact the reader came
74- * for. The field is named `unrecognized` here so the key names survive.
75- * Any field added to this record is subject to the same rule.
76- * - A Zod issue can carry the whole rejected `input` on some codes. A log
77- * record must stay bounded — the boot buffer drops any line that would
78- * overflow its budget, and a shipper truncates — which would resurrect the
79- * very failure mode above. This is also why the seams hand the *cause* here
80- * rather than passing the raw `Error` into the logger's `error` slot: that
81- * would ship the full multi-line dump plus a stack trace on every record.
66+ * Two measured reasons, not taste. The first has since LAPSED (#5573); the
67+ * second carries the decision on its own:
68+ *
69+ * - *Historical — superseded by #5573.* `ObjectLogger` used to redact
70+ * recursively by SUBSTRING: its default
71+ * `redact: ['password', 'token', 'secret', 'key']` matched any field whose
72+ * lowercased name merely *contained* one of them. A Zod `unrecognized_keys`
73+ * issue names the offending keys in a field called `keys`, and `'keys'`
74+ * contains `'key'` — so forwarding `err.issues` untouched rendered
75+ * `"keys":"***REDACTED***"` and lost the one fact the reader came for.
76+ * Redaction now matches on camelCase/snake_case WORD boundaries, so a bare
77+ * `keys` is no longer redacted and this reason no longer holds. The rule a
78+ * field added to this record is judged by today: `apiKey` / `api_key` is
79+ * redacted, `keys` / `tokens` is not.
80+ * - *Still load-bearing.* A Zod issue can carry the whole rejected `input`
81+ * on some codes. A log record must stay bounded — the boot buffer drops
82+ * any line that would overflow its budget, and a shipper truncates — which
83+ * resurrects the same failure the bullet above describes: a record that has
84+ * lost the fact the reader came for. This is also why the seams hand the
85+ * *cause* here rather than passing the raw `Error` into the logger's
86+ * `error` slot: that would ship the full multi-line dump plus a stack
87+ * trace on every record.
8288 *
8389 * So the fields are named deliberately and the list is capped, with the cap
8490 * *declared* in the record (`issueCount`) rather than silently applied.
@@ -97,8 +103,10 @@ export interface LoggedCauseIssue {
97103 message : string ;
98104 /**
99105 * The rejected key names of an `unrecognized_keys` issue. Named
100- * `unrecognized` rather than `keys` so `ObjectLogger`'s substring redactor
101- * does not replace it with `***REDACTED***`.
106+ * `unrecognized` rather than `keys` because `ObjectLogger` redacted by
107+ * substring when this was written; #5573 has since narrowed that to word
108+ * boundaries, so a field called `keys` would survive today. The name is
109+ * kept as-is — renaming a shipped log field back would be pure churn.
102110 */
103111 unrecognized ?: string [ ] ;
104112}
0 commit comments