usebruno/bruno · error · Error
Access to files outside of the collectionPath is not…
Error message
Access to files outside of the collectionPath is not allowed.
What it means
Thrown by the QuickJS local-module loader shim when the resolved path of a required local file escapes the collectionPath. The check uses path.relative: if the relative path starts with '..' or is absolute, the require is rejected. This is a security guard preventing sandboxed scripts from reading arbitrary host files.
Solutions
- Move the needed file inside the current collection directory and require it with a relative path that stays under collectionPath.
- If sharing across collections, copy or symlink the helper into the collection.
- Never interpolate untrusted values into require() paths.
Example fix
// before
const helper = require('../../shared/helper'); // escapes collection
// after — copy helper into the collection
const helper = require('./shared/helper'); Defensive patterns
Strategy: validation
Validate before calling
const path = require('path');
function isInsideCollection(target, root) {
const rel = path.relative(root, path.resolve(root, target));
return !rel.startsWith('..') && !path.isAbsolute(rel);
}
if (!isInsideCollection(reqPath, bru.cwd())) throw new Error('path outside collection'); Type guard
const isSafeRelativePath = (p, root) => { const rel = path.relative(root, path.resolve(root, p)); return !rel.startsWith('..') && !path.isAbsolute(rel); }; Try / catch
try { const m = require(maybeUnsafePath); }
catch (err) {
if (/outside of the collectionPath/.test(err.message)) {
// use a copy of the file inside the collection instead
} else throw err;
} Prevention
- Keep all required local files inside the collection directory.
- Never interpolate untrusted input into require() paths.
- Use relative paths starting with './'.
When it happens
Trigger: require('../../../etc/passwd'), require('/etc/secrets'), or require('../../other-collection/file') inside a QuickJS-sandboxed Bru script where the resolved absolute path is not within the collection directory tree.
Common situations: A shared helper legitimately lives in a sibling collection and the developer tries to reach it via ../; an imported snippet contains a path-traversal string; a variable interpolated into require() yields an unexpected absolute path.
Related errors
- Cannot find module
- Access to files outside of the allowed context roots is not…
- Cannot find module
- Error loading local module
- getRandomValues: ArrayBufferView byte length exceeds 65536
AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13).
Data as JSON: /api/errors/85328d02b4e8162b.
Report an issue: GitHub.
Appendix: source
Thrown at packages/bruno-js/src/sandbox/quickjs/shims/local-module.js:19
const path = require('path');
const fs = require('fs');
const { marshallToVm } = require('../utils');
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)