🧹 fix: Traverse Filtered Metadata, Not Raw Metadata, In debugTraverse

`debugTraverse` computes `extracted = extractMetaObject(metadata)` to
strip reserved keys, underscore-prefixed internals, and numeric splat
artifacts — but the later \`klona(metadata)\` + \`traverse\` path still
read the raw object, putting all the filtered junk back into the
rendered multi-line output.

Clone and traverse \`debugValue\` (the already-filtered object) instead.
Regression test exercises the case where numeric splat artifacts sit
alongside a real metadata field.

Reviewed-by: Codex (P2 finding on PR #12737, commit c29c18e8).
This commit is contained in:
Danny Avila 2026-04-18 12:43:12 -04:00
parent c29c18e8a1
commit 9ea11529f0
2 changed files with 24 additions and 1 deletions

View file

@ -256,6 +256,23 @@ describe('debugTraverse', () => {
expect(tenantMatches.length).toBe(1);
});
it('omits numeric splat-artifact keys from the traversed output', () => {
const info = {
level: 'error',
message: 'boom',
timestamp: 'ts',
0: 'x',
1: 'y',
realField: 'keep',
[SPLAT_SYMBOL]: [{ realField: 'keep' }],
};
const out = runFormatter(info);
expect(out).toContain('realField');
expect(out).toContain('keep');
expect(out).not.toMatch(/^\s*0:/m);
expect(out).not.toMatch(/^\s*1:/m);
});
it('surfaces unconsumed primitive SPLAT[0] (no %s in message) for debug level', () => {
const info = {
level: 'debug',

View file

@ -241,7 +241,13 @@ const debugTraverse = winston.format.printf(({ level, message, timestamp, ...met
msg += '\n{';
const copy = klona(metadata);
/*
* Traverse the filtered metadata (`debugValue`), not the raw `metadata`
* object. `extractMetaObject` strips reserved keys, underscore-prefixed
* internals, and numeric-string splat artifacts re-reading from raw
* `metadata` here would put those artifacts back into the output.
*/
const copy = klona(debugValue);
traverse(copy).forEach(function (value) {
if (typeof this?.key === 'symbol') {
return;