usebruno/bruno · error · Error
Cannot find module ${filename}
Error message
Cannot find module ${filename} What it means
Thrown by the QuickJS local-module loader shim after the path-traversal check passed but fs.existsSync(filePath) returned false. The filename (with .js appended if no extension was given) does not exist on disk under collectionPath.
Source
Thrown at packages/bruno-js/src/sandbox/quickjs/shims/local-module.js:23
const addLocalModuleLoaderShimToContext = (vm, collectionPath) => {
let loadLocalModuleHandle = vm.newFunction('loadLocalModule', function (module) {
const filename = vm.dump(module);
// Check if the filename has an extension
const hasExtension = path.extname(filename) !== '';
const resolvedFilename = hasExtension ? filename : `${filename}.js`;
// Resolve the file path and check if it's within the collectionPath
const filePath = path.resolve(collectionPath, resolvedFilename);
const relativePath = path.relative(collectionPath, filePath);
// Ensure the resolved file path is inside the collectionPath
if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) {
throw new Error('Access to files outside of the collectionPath is not allowed.');
}
if (!fs.existsSync(filePath)) {
throw new Error(`Cannot find module ${filename}`);
}
let code = fs.readFileSync(filePath).toString();
return marshallToVm(code, vm);
});
vm.setProp(vm.global, '__brunoLoadLocalModule', loadLocalModuleHandle);
loadLocalModuleHandle.dispose();
};
module.exports = addLocalModuleLoaderShimToContext;
View on GitHub (pinned to 9bdd81c7bd)
Solutions
- Confirm the file exists with the exact name and case under the collectionPath.
- Remember the shim appends .js — name your local module file with a .js extension, or pass the full filename including extension.
- If using TypeScript, transpile to .js first or require the compiled output.
Example fix
// before — only helper.ts exists
crypto.require('./helper'); // -> Cannot find module helper
// after — either rename to helper.js or pass the extension
crypto.require('./helper.js'); // after creating helper.js Defensive patterns
Strategy: validation
Validate before calling
const fs = require('fs'); const path = require('path');
function resolveLocal(name, root) {
const file = path.extname(name) ? name : name + '.js';
const full = path.join(root, file);
if (!fs.existsSync(full)) throw new Error('missing: ' + full);
return full;
} Type guard
const fileExists = (p) => { try { return fs.statSync(p).isFile(); } catch { return false; } }; Try / catch
try { const m = require('./helper'); }
catch (err) {
if (/Cannot find module/.test(err.message)) {
// create the file or fix the name
} else throw err;
} Prevention
- Name local module files with the .js extension.
- Check case on case-sensitive filesystems.
- Remember the shim resolves against collectionPath, not the calling file.
When it happens
Trigger: require('./missing-file') or require('./helper') when ./helper.js does not exist in the collection directory inside a QuickJS-sandboxed script.
Common situations: File was renamed or deleted; case mismatch on case-sensitive filesystems; the .js extension was expected but the file is .ts/.mjs and the shim only appends .js; the require path is relative to the wrong base (the shim resolves against collectionPath, not the calling file's directory).
Related errors
- Access to files outside of the collectionPath is not allowed
- Error loading local module ${moduleName}: ${error.message}
- The "size" argument must be of type number
- The "size" argument must be >= 0
- The "size" argument is too large
AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13).
Data as JSON: /api/errors/357c1c9d476eac16.
Report an issue: GitHub.