nocodb/nocodb · error · Error

Integration loader not available. This node must be executed

Error message

Integration loader not available. This node must be executed within a workflow context.

What it means

Thrown by AbstractWorkflowNode.getIntegration when this._integrationLoader is unset. The loader is injected by the workflow executor via setIntegrationLoader before node.run()/fetchOptions() execute, so a missing loader means the node instance was used outside the executor — e.g. constructed directly in a test or called from application code rather than dispatched through the workflow runtime.

Source

Thrown at packages/noco-integrations/core/src/workflow-node/types.ts:182

   * async run(ctx: WorkflowNodeRunContext) {
   *   const auth = await this.getIntegration(this.config.authIntegrationId);
   *   const data = await auth.use(async (client) => {
   *     return client.api.getData();
   *   });
   * }
   *
   * // Loading an AI integration with type
   * async run(ctx: WorkflowNodeRunContext) {
   *   const ai = await this.getIntegration<AiIntegration>(this.config.aiIntegrationId);
   *   const result = await ai.generateText({ prompt: 'Hello' });
   * }
   * ```
   */
  protected async getIntegration<T = any>(
    integrationId: string
  ): Promise<T> {
    if (!this._integrationLoader) {
      throw new Error('Integration loader not available. This node must be executed within a workflow context.');
    }
    return this._integrationLoader<T>(integrationId);
  }

  public abstract definition(): Promise<WorkflowNodeDefinition>;

  public async validate(_config: TConfig): Promise<WorkflowNodeValidationResult> {
    return { valid: true };
  }

  public abstract run(ctx: WorkflowNodeRunContext): Promise<WorkflowNodeResult>;

  public async fetchOptions(
    _key: string,
    _searchQuery?: string,
  ): Promise<unknown> {
    return []
  }

View on GitHub (pinned to d3caaf4e89)

Solutions

  1. Run the node through the workflow executor (the standard path) so setIntegrationLoader is called automatically before run/fetchOptions.
  2. In tests, call node.setIntegrationLoader(async (id) => mockIntegrationFor(id)) before invoking run/fetchOptions.
  3. Avoid constructing workflow nodes with `new` in application code — obtain them from the workflow registry/executor.
  4. If you genuinely need a node outside the executor, inject a loader explicitly before any method that calls getIntegration.

Example fix

// before (test)
const node = new MyNode();
await node.run({}); // throws: Integration loader not available...

// after
const node = new MyNode();
node.setIntegrationLoader(async (id) => mockIntegrations[id]);
await node.run({});
Defensive patterns

Strategy: validation

Validate before calling

function nodeHasLoader(node: any): boolean {
  return typeof node?._integrationLoader === 'function';
}

if (!nodeHasLoader(node)) {
  throw new Error('Refusing to call run() on a node without an integration loader; run via the workflow executor.');
}

Type guard

function isDispatchableNode<N extends { _integrationLoader?: unknown }>(
  node: N,
): node is N & { _integrationLoader: (id: string) => Promise<unknown> } {
  return typeof node._integrationLoader === 'function';
}

Try / catch

try {
  await node.run(ctx);
} catch (err) {
  if (err instanceof Error && /Integration loader not available/.test(err.message)) {
    // surface 'attach this node to a workflow first' to the user / test author
    throw new Error('Node must be executed within a workflow context');
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling node.getIntegration('id') (transitively: node.run, node.fetchOptions, or any override that calls getIntegration) on a node instance that was constructed with `new MyNode()` directly rather than instantiated and dispatched by the workflow executor. Also when a node method is invoked before the executor has called setIntegrationLoader, or in unit tests that exercise run() without wiring the loader.

Common situations: Unit tests that `new MyNode()` and call .run() without injecting a loader; a node class whose fetchOptions is hit by the UI before the node is attached to a workflow; refactoring that moves getIntegration calls out of run() into a constructor/standalone helper that runs before the executor sets the loader.

Related errors


AI-assisted analysis of nocodb/nocodb@d3caaf4e89 (2026-08-12). Data as JSON: /api/errors/58abe7d5ed95dda6. Report an issue: GitHub.