cube-js/cube · error · UserError
'${modulePath}' restricted
Error message
'${modulePath}' restricted What it means
DataSchemaCompiler.resolveModuleFile resolves a module import from data model JS files to a path under node_modules. If the resolved absolute path escapes the project's node_modules directory (e.g. via '../' traversal or an absolute path), and allowNodeRequire is not enabled, the compiler refuses the import with UserError ''${modulePath}' restricted'. This is a sandbox/security guard so data models can only load whitelisted packages.
Source
Thrown at packages/cubejs-schema-compiler/src/compiler/DataSchemaCompiler.ts:1003
if (!currentFile.isModule && localImport) {
const fileName = localImport[1].match(/^.*\.js$/) ? localImport[1] : `${localImport[1]}.js`;
const foundFile = toCompile.find((f) => f.fileName === fileName);
if (!foundFile) {
throw new UserError(`Required import for ${fileName} is not found`);
}
return foundFile;
}
const nodeModulesPath = path.resolve('node_modules');
let absPath = currentFile.isModule ?
path.resolve('node_modules', path.dirname(currentFile.fileName), modulePath) :
path.resolve('node_modules', modulePath);
if (!absPath.startsWith(nodeModulesPath)) {
if (this.allowNodeRequire) {
return null;
}
throw new UserError(`'${modulePath}' restricted`);
}
const packagePath = absPath.replace(nodeModulesPath, '').split('/').filter(s => !!s)[0];
if (!packagePath) {
if (this.allowNodeRequire) {
return null;
}
throw new UserError(`'${modulePath}' is incorrect`);
}
if (!this.isWhiteListedPackage(packagePath)) {
if (this.allowNodeRequire) {
return null;
}
throw new UserError(`Package '${packagePath}' not found`);
}
if (fs.existsSync(absPath)) {
const stat = fs.lstatSync(absPath);
if (stat.isDirectory()) {
absPath = path.resolve(absPath, 'index.js');View on GitHub (pinned to 7d981676b3)
Solutions
- Move the imported file into the project so it resolves under node_modules, or into the schema folder for relative imports
- Enable allowNodeRequire in compiler options if arbitrary Node requires are acceptable in your environment
- Inline or re-export the needed code through a whitelisted npm package installed in node_modules
Example fix
// before
import { formatDate } from '../shared/format';
// after
import { formatDate } from './format'; // file placed inside the schema folder Defensive patterns
Strategy: validation
Validate before calling
const path = require('path');
function isAllowedImport(modulePath) {
const abs = path.resolve('node_modules', modulePath);
return abs.startsWith(path.resolve('node_modules'));
}
if (!isAllowedImport('./../shared/foo')) throw new Error('import escapes node_modules'); Try / catch
try {
await compiler.compile();
} catch (e) {
if (String(e.message).endsWith("' restricted")) {
console.error('Data model import outside node_modules:', e.message);
}
} Prevention
- Keep schema helper files inside the schema folder and use './' relative imports
- Never use '../' or absolute paths in data model imports
- Distribute shared code as an npm package installed in node_modules
When it happens
Trigger: Importing a module from a JS data model whose resolved path is not under node_modules: relative imports like '../shared/foo.js' that climb out of the schema folder, absolute paths, or imports that path.resolve normalizes outside node_modules while compile flags run without allowNodeRequire.
Common situations: Developers moving shared schema helpers outside the project, using path traversal in require/import statements, or running in environments (Cube Cloud / compiler API) where allowNodeRequire is disabled by default.
Related errors
- Package '${packagePath}' not found
- '${modulePath}' is incorrect
- Path '${absPath.replace(nodeModulesPath + '/', '')}' not fou
- maskedMembers cannot be provided in the query
- You cannot change security context via __user from ${session
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/a182736306773ec9.
Report an issue: GitHub.