Repository navigation
fix(logging): keep the component and apply printf formats in the app log - #10770
Merged
diegosouzapw merged 3 commits intoAug 20, 2026
Conversation
Two defects in the same formatting path of consoleInterceptor. extractComponent took the first bracket of the message. The in-repo tagged logger emits "[LEVEL] [TAG] message" (open-sse/utils/logger.ts), so entries were filed under the level and the real component was dropped — the log stopped being filterable by component, which is the point of the field. Level tokens are now skipped; the level already travels in the entry's own field. argsToMessage joined the arguments instead of formatting them, so printf format strings stayed literal with their values trailing behind, unlabelled. That is not sloppiness on the caller side: src/server/ws/liveServer.ts passes %s/%d deliberately, to keep client-supplied values out of the format slot (CWE-134). util.format is applied only when the first argument is a string containing a specifier, and it appends surplus arguments exactly like the previous join, so calls without a format string keep byte-identical output.
…ke a format string argsToMessage() took the printf path whenever the first argument contained any %s/%d/%i/%f/%j/%o/%O/%c substring — including dynamic content like a hook or tag name that is not a deliberate format string. When that happened with a trailing Error argument, util.format() consumed the Error as the substitution value and dropped its message and stack from the app log. Skip the printf path whenever a trailing argument is an Error, so those calls keep the full message+stack formatting regardless of what the first argument's text contains.
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…log (diegosouzapw#10770) Merged via merge-train (release/v3.8.50, batch1 2026-08-20) — static gates (typecheck/file-size/complexity/cognitive/changelog) green on the combined tree; test:unit reds observed in the boarded run were verified pre-existing on the pure release tip (unrelated flake), not caused by this PR. Thanks for the contribution!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two defects in the same formatting path of
consoleInterceptor, both visible in a live app log.extractComponenttakes the first bracketed group in a message as the component name. Thein-repo tagged logger emits
[LEVEL] [TAG] message(open-sse/utils/logger.ts), so every taggedentry recorded its level as the component instead — 2,349 of 35,471 lines filed under
"component":"INFO"on a measured instance. Level tokens are now skipped, so the real tag survives.argsToMessagejoined arguments with spaces instead of formatting them, so printf strings stayedliteral with their values trailing behind, unlabelled — 4,736 lines with unsubstituted
placeholders on the same log.
src/server/ws/liveServer.tsuses%s/%ddeliberately, to keepclient-supplied values out of the format slot (CWE-134 hardening) —
util.formatis now appliedwhen the first argument looks like a format string, appending any surplus arguments exactly like
the previous join.
A trailing
Errorargument is exempted from the printf path: some call sites build their firstargument from dynamic content (a hook or tag name) that can coincidentally contain a
%s-likesubstring, and
util.formatwould otherwise consume the Error as a substitution value and dropits stack from the log.
Related Issues
Validation
node --test tests/unit/console-interceptor-message-fidelity.test.ts(2/2),npm run test:vitest(368/368)npm run lintrelease/v3.8.50Tests Added Or Updated
tests/unit/console-interceptor-message-fidelity.test.ts(new)Coverage Notes
Touches only
src/lib/consoleInterceptor.ts. Both formatting defects and the Error-swallowingedge case are each covered by a dedicated assertion in the new test file.
Reviewer Notes
LEVEL_TOKENSis a small hardcoded set of level words, kept in sync by comment withopen-sse/utils/logger.ts'sLEVELSrather than importing it:LEVELSonly has 4 keys(
debug/info/warn/error) and doesn't coverWARNING/FATAL/TRACE, which also appear asbracket tags elsewhere in the codebase.