{"record":{"id":"96ba33dd0392b3a0","repo":"pinojs/pino","slug":"callback-must-be-a-function","errorCode":null,"errorMessage":"callback must be a function","messagePattern":"callback must be a function","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/proto.js","lineNumber":248,"sourceCode":"    obj = mixinMergeStrategy(obj, mixin(obj, num, this))\n  }\n\n  const s = this[asJsonSym](obj, msg, num, t)\n\n  const stream = this[streamSym]\n  if (stream[needsMetadataGsym] === true) {\n    stream.lastLevel = num\n    stream.lastObj = obj\n    stream.lastMsg = msg\n    stream.lastTime = t.slice(this[timeSliceIndexSym])\n    stream.lastLogger = this // for child loggers\n  }\n  stream.write(streamWriteHook ? streamWriteHook(s) : s)\n}\n\nfunction flush (cb) {\n  if (cb != null && typeof cb !== 'function') {\n    throw Error('callback must be a function')\n  }\n\n  const stream = this[streamSym]\n\n  if (typeof stream.flush === 'function') {\n    stream.flush(cb || noop)\n  } else if (cb) cb()\n}\n","sourceCodeStart":230,"sourceCodeEnd":257,"githubUrl":"https://github.com/pinojs/pino/blob/5aa62305c57709ebd6f6b7c328e8830eeb29b297/lib/proto.js#L230-L257","documentation":"flush(cb) accepts an optional callback but strictly rejects any non-function, non-nullish argument. The callback is invoked once the underlying stream has been flushed, so pino validates its type up front to avoid a confusing async TypeError later.","triggerScenarios":"logger.flush('cb'); logger.flush(true); passing something truthy but not callable, e.g. flush(options) or flush(stream) by mistake.","commonSituations":"Confusing flush with an options-taking API; passing a promise resolver incorrectly or a renamed variable that no longer holds a function.","solutions":["Pass a function: logger.flush(() => { ... }) or omit the argument entirely (logger.flush()).","If you need completion semantics without a callback, pass a function that resolves your promise.","Check the call site for accidentally forwarded non-function arguments.","Note flush(cb != null) — only null/undefined are allowed as 'no callback'; use those, not false."],"exampleFix":"// before\nlogger.flush(true)\n// after\nlogger.flush((err) => { if (err) console.error(err) })","handlingStrategy":"type-guard","validationCode":"function safeFlush(logger, cb) {\n  if (cb != null && typeof cb !== 'function') {\n    throw new TypeError('flush expects a function callback or nothing')\n  }\n  logger.flush(cb || undefined)\n}","typeGuard":"function isFlushCallback(cb) {\n  return cb == null || typeof cb === 'function'\n}","tryCatchPattern":"try {\n  logger.flush(onFlushed)\n} catch (e) {\n  if (e.message === 'callback must be a function') {\n    logger.flush() // proceed without callback\n  } else throw e\n}","preventionTips":["Call flush() with either nothing or an explicit function.","Wrap promise-style usage: logger.flush(() => resolve()).","Never forward arbitrary arguments (options/streams) into flush().","Guard callbacks that may be undefined: flush(cb || undefined)."],"tags":["api-misuse","logging","invalid-argument"],"backgroundTag":"callback-must-be-function","analyzedSha":"5aa62305c57709ebd6f6b7c328e8830eeb29b297","analyzedAt":"2026-09-02T22:05:21.418Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}