From b80fc0f096400c22fe1c447ed6305f83e8a19b11 Mon Sep 17 00:00:00 2001 From: JSap0914 Date: Tue, 23 Jun 2026 21:23:36 +0900 Subject: [PATCH] fix: enabled returns undefined instead of false when DEBUG is not set When enable() is called with a non-string argument (including undefined, which happens at startup when process.env.DEBUG is absent), it assigns createDebug.namespaces = undefined. The per-instance enabled getter caches results using namespacesCache, which is initialised to undefined in the closure. The cache-miss guard if (namespacesCache !== createDebug.namespaces) therefore evaluates to false on the very first access (undefined !== undefined is false), so createDebug.enabled(namespace) is never invoked, and enabledCache stays undefined. Every subsequent read of instance.enabled returns undefined instead of false until a second, string-valued enable() call is made. Fix: normalise createDebug.namespaces to an empty string whenever the argument is not a string, consistent with how the split step already treats non-string input. --- src/common.js | 2 +- test.js | 31 ++++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/common.js b/src/common.js index 141cb578..a3ae3b24 100644 --- a/src/common.js +++ b/src/common.js @@ -161,7 +161,7 @@ function setup(env) { */ function enable(namespaces) { createDebug.save(namespaces); - createDebug.namespaces = namespaces; + createDebug.namespaces = typeof namespaces === 'string' ? namespaces : ''; createDebug.names = []; createDebug.skips = []; diff --git a/test.js b/test.js index a1d6f633..83f2ebc3 100644 --- a/test.js +++ b/test.js @@ -137,4 +137,33 @@ describe('debug', () => { assert.deepStrictEqual(messages, ['test2', 'test3']); }); }); -}); + + describe('enabled before any explicit enable() call', () => { + it('returns false (not undefined) when DEBUG env var is absent', () => { + // Regression: when enable() is called with undefined (e.g. DEBUG is + // not set), createDebug.namespaces is set to undefined. The per-instance + // cache initialises namespacesCache to undefined too, so the cache + // comparison `namespacesCache !== createDebug.namespaces` evaluates to + // false and enabled() is never invoked, leaving enabledCache as + // undefined rather than false. + const savedDebug = process.env.DEBUG; + delete process.env.DEBUG; + // Re-create a fresh debug factory with no DEBUG env var + Object.keys(require.cache).forEach(k => { + if (k.includes('debug/src')) { + delete require.cache[k]; + } + }); + const freshDebug = require('./src'); + const log = freshDebug('test:namespace'); + assert.strictEqual(typeof log.enabled, 'boolean', + 'enabled should be a boolean, not ' + typeof log.enabled); + assert.strictEqual(log.enabled, false, + 'enabled should be false when no namespaces are active'); + // Restore + if (savedDebug !== undefined) { + process.env.DEBUG = savedDebug; + } + }); + }); +}); \ No newline at end of file