denoland/deno · error · Error
Cannot create mock because named exports cannot be applied t
Error message
Cannot create mock because named exports cannot be applied to the provided default export.
What it means
When a module mock supplies both named exports and a default export, the generated CommonJS shim sets module.exports = defaultExport and then copies each named export onto it, which only works if the default is an object. The shim's guard (module.exports === null || typeof module.exports !== 'object') throws kBadExportsMessage, so a function, primitive, or null default combined with namedExports fails at require() time.
Source
Thrown at ext/node/polyfills/testing.ts:3180
}
function registryAccessSource() {
return "globalThis[Symbol.for(" + JSONStringify(kMockModuleRegistryName) +
")]";
}
function generateCjsSource(entry, key) {
let src = '"use strict";\n';
src += "const $e = " + registryAccessSource() + ".get(" +
JSONStringify(key) + ");\n";
src += "if ($e === undefined) { throw new Error(" +
JSONStringify('mock exports not found for "' + key + '"') + "); }\n";
if (entry.hasDefaultExport) {
src += "module.exports = $e.moduleExports.default;\n";
}
if (entry.exportNames.length > 0) {
src += "if (module.exports === null || typeof module.exports !== " +
'"object") { throw new Error(' + JSONStringify(kBadExportsMessage) +
"); }\n";
for (let i = 0; i < entry.exportNames.length; i++) {
const name = entry.exportNames[i];
src += "module.exports[" + JSONStringify(name) + "] = " +
"$e.moduleExports[" + JSONStringify(name) + "];\n";
}
}
return src;
}
function generateEsmSource(entry, key) {
let src = "const $e = " + registryAccessSource() + ".get(" +
JSONStringify(key) + ");\n";
src += "if ($e === undefined) { throw new Error(" +
JSONStringify('mock exports not found for "' + key + '"') + "); }\n";
if (entry.isCjs) {
// For a CommonJS module the named exports are applied onto the default
// export object, mirroring how Deno exposes a required CJS module to anView on GitHub (pinned to 9ad36f7a2c)
Solutions
- Expose the function as a named export instead: namedExports: { connect: fn, ... }
- Omit defaultExport entirely so the shim builds its own empty object to carry named exports
- Keep the function/primitive defaultExport but remove namedExports from options
- Wrap everything in a plain-object defaultExport and have consumers destructure it
Example fix
// before
mock.module('pg', { defaultExport: function query() {}, namedExports: { Pool: class {} } });
// after
mock.module('pg', { namedExports: { query: () => {}, Pool: class {} } }); Defensive patterns
Strategy: validation
Validate before calling
function mockCjsModule(spec: string, defaultExport: unknown, namedExports: Record<string, unknown> | undefined): void {
const hasNamed = namedExports !== undefined && Object.keys(namedExports).length > 0;
if (hasNamed && (defaultExport === null || typeof defaultExport !== 'object')) {
throw new Error('namedExports need an object defaultExport; move the function to a named export');
}
mock.module(spec, defaultExport === undefined ? { namedExports } : { defaultExport, namedExports });
} Prevention
- Never combine a callable default with namedExports in a module mock
- Keep CJS function-style packages as named-export mocks
- Add a setup-time assertion that the default export is an object when named exports are present
When it happens
Trigger: mock.module('pkg', { defaultExport: () => {}, namedExports: { version: '1' } }); defaultExport: 'text' with namedExports; defaultExport: null plus namedExports.
Common situations: Mocking CommonJS packages whose real module.exports is a function while also wanting named members; converting ESM-style mock fixtures to CJS-shaped ones.
Related errors
- mock exports not found for "${key}"
- Empty filepath.
- Module already loaded
- ERR_INVALID_ARG_TYPE
- test was expected to fail but passed
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/54a82cb4a7b07b6a.
Report an issue: GitHub.