{"record":{"id":"7fb62f634a272196","repo":"denoland/deno","slug":"empty-filepath","errorCode":null,"errorMessage":"Empty filepath.","messagePattern":"Empty filepath\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/01_require.js","lineNumber":511,"sourceCode":"}\nsetupBuiltinModules();\n\n// Loading node:module has to bootstrap node:process. `_next_tick.ts`'s\n// `nextTick()` returns without queueing anything until `enableNextTick()` runs,\n// and that only happens inside `__bootstrapNodeProcess()` (node:process's\n// deferred trigger). Anything reaching `process.nextTick` before then - e.g.\n// `_events.mjs`'s `addCatch`, which routes a rejected handler promise to the\n// `error` event under `captureRejections` - silently loses its callback.\n//\n// This used to happen by accident: the eager `vm.js` load above did\n// `createLazyLoader(\"node:process\")()` at its module body. Now that the builtin\n// map is lazy, say it on purpose. node:process's closure is ~7 modules and\n// every CommonJS entry point pulls it in anyway.\ncore.createLazyLoader(\"node:process\")();\n\nfunction pathDirname(filepath) {\n  if (filepath == null) {\n    throw new Error(\"Empty filepath.\");\n  } else if (filepath === \"\") {\n    return \".\";\n  }\n  return op_require_path_dirname(filepath);\n}\n\nfunction pathResolve(...args) {\n  return op_require_path_resolve(args);\n}\n\nconst nativeModulePolyfill = new SafeMap();\n\nconst relativeResolveCache = ObjectCreate(null);\nlet requireDepth = 0;\nlet statCache = null;\nlet mainModule = null;\nlet hasBrokenOnInspectBrk = false;\nlet hasInspectBrk = false;","sourceCodeStart":493,"sourceCodeEnd":529,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/01_require.js#L493-L529","documentation":"pathDirname is an internal helper of Deno's CommonJS compat layer (ext/node/polyfills/01_require.js); it throws this generic Error when the filepath handed to it is null or undefined. Note the asymmetry: an empty string returns '.', so only nullish values throw. End users normally hit it when CJS module resolution produced no filename - a malformed require target or a gap in the polyfill machinery - not through a public API they called directly.","triggerScenarios":"A require() whose specifier resolves to a nullish filename inside the CJS loader; custom resolve/load hooks returning malformed results that leave filename unset; interplay between the eager builtin-map loading and a package expecting a path.","commonSituations":"Bundled npm packages exercising corner cases of Deno's require polyfill; registerHooks-based loaders returning bad URLs; older Deno versions with resolution gaps that were fixed later.","solutions":["Upgrade Deno - node/require interop fixes land in nearly every release","Reproduce with a minimal require('the-package') and confirm the specifier is a non-empty, valid string","If it originates from your own module hooks, make sure resolve hooks always return a real URL and load hooks a real filename"],"exampleFix":"// before (custom hook returning a malformed result)\nregisterHooks({\n  resolve(spec, ctx, next) {\n    if (spec.startsWith('virtual:')) return; // undefined filename leaks downstream\n    return next(spec, ctx);\n  },\n});\n\n// after\nregisterHooks({\n  resolve(spec, ctx, next) {\n    if (spec.startsWith('virtual:')) {\n      return { shortCircuit: true, url: pathToFileURL(spec.slice(8)).href };\n    }\n    return next(spec, ctx);\n  },\n});","handlingStrategy":"try-catch","validationCode":"function requireSafe(id: string): unknown {\n  if (typeof id !== 'string' || id.length === 0) {\n    throw new TypeError(`require() needs a non-empty specifier, got: ${String(id)}`);\n  }\n  return require(id);\n}","typeGuard":"function isNonEmptyPath(p: unknown): p is string {\n  return typeof p === 'string' && p.length > 0;\n}","tryCatchPattern":"try {\n  const mod = require(specifier);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Empty filepath.') {\n    // internal CJS resolution produced no filename: log specifier and report upstream\n    throw new Error(`module resolution returned no path for '${specifier}' (Deno CJS interop)`);\n  }\n  throw e;\n}","preventionTips":["Keep Deno updated - node/require interop gaps are fixed continuously","Never pass possibly-null path or specifier values into require-based loaders","When writing registerHooks hooks, always return well-formed URLs/filenames from every path"],"tags":["deno","node-compat","commonjs","require","internal-error"],"backgroundTag":"invalid-path-argument","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-26T07:17:17.940Z"}