pinojs/pino · error · Error
missing bindings for child Pino
Error message
missing bindings for child Pino
What it means
pino().child() requires a bindings object as its first argument. The browser build's child function (browser.js:208) throws immediately when bindings is falsy because a child logger must inherit at least an empty set of bindings to derive its identity.
Source
Thrown at browser.js:208
throw Error('unknown level ' + level)
}
this._level = level
set(this, setOpts, logger, 'error') // <-- must stay first
set(this, setOpts, logger, 'fatal')
set(this, setOpts, logger, 'warn')
set(this, setOpts, logger, 'info')
set(this, setOpts, logger, 'debug')
set(this, setOpts, logger, 'trace')
customLevels.forEach((level) => {
set(this, setOpts, logger, level)
})
}
function child (setOpts, bindings, childOptions) {
if (!bindings) {
throw new Error('missing bindings for child Pino')
}
childOptions = childOptions || {}
if (serialize && bindings.serializers) {
childOptions.serializers = bindings.serializers
}
const childOptionsSerializers = childOptions.serializers
if (serialize && childOptionsSerializers) {
var childSerializers = Object.assign({}, serializers, childOptionsSerializers)
var childSerialize = opts.browser.serialize === true
? Object.keys(childSerializers)
: serialize
delete bindings.serializers
applySerializers([bindings], childSerialize, childSerializers, this._stdErrSerialize)
}
function Child (parent) {
this._childLevel = (parent._childLevel | 0) + 1
// make sure bindings are available in the `set` functionView on GitHub (pinned to 5aa62305c5)
Solutions
- Pass a bindings object as the first argument, even if empty: logger.child({})
- Move any contextual fields (requestId, module name) into the bindings object
- If you intended to pass only childOptions, pass bindings first: logger.child({}, childOptions)
Example fix
// before
const child = logger.child();
// after
const child = logger.child({ module: 'payments' }); Defensive patterns
Strategy: validation
Validate before calling
function safeChild(logger, bindings) {
if (bindings == null || typeof bindings !== 'object') {
throw new TypeError('child() requires a bindings object');
}
return logger.child(bindings);
} Type guard
function hasBindings(b) { return typeof b === 'object' && b !== null; } Try / catch
try { const child = logger.child(bindings); } catch (e) { if (e.message === 'missing bindings for child Pino') { child = logger.child({}); } else { throw e; } } Prevention
- Always pass an object to child(), even when there is nothing to bind: child({})
- Wrap logger.child in a factory helper that enforces the bindings argument
- Enable lint rules or code review checks for child() calls with zero arguments
When it happens
Trigger: Calling logger.child() with no arguments, or explicitly with undefined/null as the first argument, e.g. logger.child().
Common situations: Migrating from other logging libraries (like winston's child or custom factories) that allow argument-less child(); refactoring code that removed bindings but left the child() call; forgetting to pass { reqId } style context.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- only one of target or targets can be specified
- pino – redact must contain an array of strings
- pino: transmit option must have a send function
- unknown level ${level}
- Levels comparison should be one of "ASC", "DESC" or "functio
AI-assisted analysis of pinojs/pino@5aa62305c5 (2026-09-02).
Data as JSON: /api/errors/9d37894524a3aa97.
Report an issue: GitHub.