usebruno/bruno · error · Error
Cannot find module ${moduleName}
Error message
Cannot find module ${moduleName} What it means
Thrown by loadLocalModule when the resolved module file does not exist on disk. After all security checks pass, the loader calls fs.existsSync(normalizedFilePath) at cjs-loader.js:166; if the file is not found, this error is thrown. This mirrors Node.js's native 'Cannot find module' error for the sandboxed require context.
Source
Thrown at packages/bruno-js/src/sandbox/node-vm/cjs-loader.js:167
// Resolve the module path, handling files and directories
const normalizedFilePath = resolveLocalModulePath(currentModuleDir, moduleName);
// Final security check after resolution
if (!isPathWithinAllowedRoots(normalizedFilePath, additionalContextRootsAbsolute)) {
const allowedRootsDisplay = additionalContextRootsAbsolute.map((root) => ` - ${root}`).join('\n');
throw new Error(
`Access to files outside of the allowed context roots is not allowed: ${moduleName}\n\n`
+ `Allowed context roots:\n${allowedRootsDisplay}`
);
}
// Check cache - we cache moduleObj, return its exports
if (localModuleCache.has(normalizedFilePath)) {
return localModuleCache.get(normalizedFilePath).exports;
}
if (!fs.existsSync(normalizedFilePath)) {
throw new Error(`Cannot find module ${moduleName}`);
}
const moduleCode = fs.readFileSync(normalizedFilePath, 'utf8');
const moduleObj = { exports: {} };
const moduleDir = path.dirname(normalizedFilePath);
// Pre-populate cache with moduleObj BEFORE execution to handle circular dependencies
// This allows re-entrant requires to get partial exports (Node.js behavior)
// We cache moduleObj (not moduleObj.exports) so that module.exports reassignment works
localModuleCache.set(normalizedFilePath, moduleObj);
// Create require function for nested imports
const moduleRequire = createCustomRequire({
collectionPath,
isolatedContext,
currentModuleDir: moduleDir,
localModuleCache,
additionalContextRootsAbsoluteView on GitHub (pinned to 9bdd81c7bd)
Solutions
- Verify the file exists at the expected path relative to the current script.
- Check for typos and case mismatches in the filename (Linux is case-sensitive).
- Ensure the file has a .js extension or is an index.js inside a directory of that name.
- Use the correct relative path prefix (./ for same directory, ../ for parent).
Example fix
// before
const helper = require('./helper'); // file is actually helpers.js (plural)
// after
const helper = require('./helpers'); // matches helpers.js Defensive patterns
Strategy: validation
Validate before calling
const path = require('path');
const fs = require('fs');
function moduleExists(currentDir, modulePath) {
const basePath = path.resolve(currentDir, modulePath);
if (path.extname(modulePath) && fs.existsSync(basePath)) return true;
if (fs.existsSync(basePath + '.js')) return true;
if (fs.existsSync(basePath) && fs.statSync(basePath).isDirectory()) {
if (fs.existsSync(path.join(basePath, 'index.js'))) return true;
const pkg = path.join(basePath, 'package.json');
if (fs.existsSync(pkg)) {
const main = JSON.parse(fs.readFileSync(pkg, 'utf8')).main;
if (main && fs.existsSync(path.resolve(basePath, main))) return true;
}
}
return false;
}
// before requiring: if (moduleExists(__dirname, modulePath)) require(modulePath); Try / catch
try {
const mod = require(modulePath);
} catch (e) {
if (e.message.startsWith('Cannot find module')) {
console.error('Module file not found. Check path, extension, and case:', modulePath);
}
} Prevention
- Verify the file exists before requiring it.
- Check for typos and case-sensitivity issues (Linux is case-sensitive).
- Ensure the file has a .js extension or is resolvable as a directory with index.js.
When it happens
Trigger: Calling require('./helpers') when there is no helpers.js, helpers/index.js, or helpers/package.json in the current module's directory. The resolution algorithm at cjs-loader.js:19-60 tries the exact path, path + .js, directory + package.json main, and directory + index.js before falling back to the raw path, which then fails the existsSync check.
Common situations: Typo in the module path. Forgetting to add the .js extension (the loader tries it automatically, but only for the last path segment). Importing a file that has not been created yet. Case-sensitivity issues on Linux (e.g., requiring './Utils' when the file is 'utils.js').
Related errors
- Access to files outside of the allowed context roots is not
- Cannot find module ${filename}
- Cannot find module ${mod}
AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13).
Data as JSON: /api/errors/7383b3d8022e658e.
Report an issue: GitHub.