Skip to content

[Bug]: After using format.splat(), the log output is abnormal when the message contains special characters #2572

@gongshun

Description

@gongshun

🔎 Search Terms

string interpolation,%c,special characters

The problem

With format.splat() enabled, when the log message contains a %c-like placeholder:

  • %c gets swallowed, so hello %c world becomes hello world;
  • if the last argument is a plain object carrying custom fields (e.g. { robotId: 5 }), it is not merged into the output (fields are lost).

Is this expected behavior or a bug? If expected, what’s the recommended way to keep such “non-printf” placeholders literal while still merging the trailing object as meta when using splat?

What version of Winston presents the issue?

v3.5.0

What version of Node are you using?

v22.11.0

If this worked in a previous version of Winston, which was it?

No response

Minimum Working Example

const { createLogger, format, transports } = require('winston');

const logger = createLogger({
  level: 'info',
  format: format.combine(
    format.splat(),
    format.printf(info => {
      const { level, message, ...rest } = info;
      return JSON.stringify({ level, message, ...rest });
    })
  ),
  transports: [new transports.Console()],
});

// normal work
logger.info('hello %s world', 'x', { robotId: 5 });
logger.info('hello world', { robotId: 5 });

// when the message contains %c, %c is swallowed; and the custom field is lost
logger.info('hello %c world', { robotId: 5 });

Additional information

  • Expected Output
{"level":"info","message":"hello x world","robotId":5}
{"level":"info","message":"hello world","robotId":5}
{"level":"info","message":"hello %c  world","robotId":5}
  • Actual output
{"level":"info","message":"hello x world","robotId":5}
{"level":"info","message":"hello world","robotId":5}
{"level":"info","message":"hello  world"}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions