cube-js/cube · error · UserError

COMPILE_CONTEXT can't be used unless contextToAppId is defin

Error message

COMPILE_CONTEXT can't be used unless contextToAppId is defined. Please see https://cube.dev/docs/config#options-reference-context-to-app-id.

What it means

standaloneCompileContextProxy returns a Proxy whose every property access throws this UserError. It is installed when COMPILE_CONTEXT is referenced but the app has not configured contextToAppId, meaning compile-time context switching (per-app compiling) is not possible. The error tells you to enable multitenant compilation first.

Source

Thrown at packages/cubejs-schema-compiler/src/compiler/DataSchemaCompiler.ts:977

      });
    } catch (e) {
      errorsReport.error(e);
    }
  }

  // Alias "securityContext" with "security_context" (snake case version)
  // to support snake case based data models
  private cloneCompileContextWithGetterAlias(compileContext) {
    const ctx = compileContext || {};
    const clone = R.clone(ctx);
    clone.security_context = ctx.securityContext;
    return clone;
  }

  private standaloneCompileContextProxy() {
    return new Proxy({}, {
      get: () => {
        throw new UserError('COMPILE_CONTEXT can\'t be used unless contextToAppId is defined. Please see https://cube.dev/docs/config#options-reference-context-to-app-id.');
      }
    });
  }

  private resolveModuleFile(currentFile: FileContent, modulePath: string, toCompile: FileContent[], errorsReport: ErrorReporter) {
    const localImport = modulePath.match(/^\.\/(.*)$/);

    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 ?

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Define `contextToAppId` (and typically `contextToOrchestratorId`) in your cube.js configuration options.
  2. Return a stable app id per security context so each context compiles its own schema.
  3. If you don't need compile-time multitenancy, remove COMPILE_CONTEXT usage from the data models.
  4. Verify the compile request actually carries a security context so contextToAppId can resolve.

Example fix

// before
// cube.js: no multitenant config, schema uses COMPILE_CONTEXT
// after
module.exports = {
  contextToAppId: ({ securityContext }) => `APP_${securityContext?.tenantId}`,
  contextToOrchestratorId: ({ securityContext }) => `APP_${securityContext?.tenantId}`,
};
Defensive patterns

Strategy: validation

Validate before calling

if (!options.contextToAppId && /COMPILE_CONTEXT/.test(schemaSource)) {
  throw new Error('Schemas use COMPILE_CONTEXT; define contextToAppId in options');
}

Type guard

function canUseCompileContext(opts) { return typeof opts.contextToAppId === 'function'; }

Try / catch

try { await compiler.compile(); } catch (e) { if (/COMPILE_CONTEXT can't be used/.test(e.message)) { console.error('Add contextToAppId to cube.js config or remove COMPILE_CONTEXT'); } throw e; }

Prevention

When it happens

Trigger: A data model references `${COMPILE_CONTEXT.something}` (e.g. to build per-tenant schemas) while the server config lacks `contextToAppId`, or COMPILE_CONTEXT is accessed during a compile that isn't running in per-context mode.

Common situations: Adding COMPILE_CONTEXT to schemas for multitenancy but forgetting the required config options; running a single-tenant dev server against schemas copied from a multitenant project; accessing COMPILE_CONTEXT outside the intended compilation path.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/a18e66893902db51. Report an issue: GitHub.