immich-app/immich · error · BadRequestException

Method "${step.method}" is incompatible with workflow trigge

Error message

Method "${step.method}" is incompatible with workflow trigger: "${trigger}"

What it means

A BadRequestException (HTTP 400) thrown by WorkflowService.resolveAndValidateSteps when the resolved plugin method's declared WorkflowType set is not compatible with the workflow's trigger. isMethodCompatible checks whether any of the trigger's valid types (from triggerMap) appear in the method's type set (or its inferred supertypes); if not, the method cannot handle that trigger.

Source

Thrown at server/src/services/workflow.service.ts:97

  }

  async delete(auth: AuthDto, id: string): Promise<void> {
    await this.requireAccess({ auth, permission: Permission.WorkflowDelete, ids: [id] });
    await this.workflowRepository.delete(id);
  }

  private async resolveAndValidateSteps<T extends { method: string }>(steps: T[], trigger: WorkflowTrigger) {
    const methods = await this.pluginRepository.getForValidation();
    const results: Array<T & { pluginMethod: PluginMethodSearchResponse }> = [];

    for (const step of steps) {
      const pluginMethod = resolveMethod(methods, step.method);
      if (!pluginMethod) {
        throw new BadRequestException(`Unknown method ${step.method}`);
      }

      if (!isMethodCompatible(pluginMethod, trigger)) {
        throw new BadRequestException(`Method "${step.method}" is incompatible with workflow trigger: "${trigger}"`);
      }

      results.push({ ...step, pluginMethod });
    }

    // TODO make sure all steps can use a common WorkflowType

    return results;
  }

  private findOrFail(id: string) {
    return findOrFail(() => this.workflowRepository.get(id), 'Workflow');
  }
}

View on GitHub (pinned to 199723261c)

Solutions

  1. Choose a method whose declared types include the WorkflowType associated with the trigger (AssetV1 for AssetCreate / AssetMetadataExtraction).
  2. Change the workflow trigger to one the method supports.
  3. Ask the plugin author to add the missing WorkflowType to the method's declaration.
  4. Validate trigger/method compatibility client-side using the trigger list and method search results.

Example fix

// before: trigger=AssetCreate, method only declares AssetPersonV1
{ "trigger": "AssetCreate", "steps": [{ "method": "p#onPerson" }] }

// after: use a method that declares AssetV1
{ "trigger": "AssetCreate", "steps": [{ "method": "p#onAsset" }] }
Defensive patterns

Strategy: validation

Validate before calling

function isStepCompatibleWithTrigger(method, trigger) {
  // mirror server's isMethodCompatible using triggerMap from /workflows/triggers
  const validTypes = triggerMap[trigger];
  return method.types.some((t) => validTypes.includes(t));
}
for (const step of steps) {
  if (!isStepCompatibleWithTrigger(step.pluginMethod, trigger)) {
    return badRequest(`Method ${step.method} incompatible with ${trigger}`);
  }
}

Type guard

const isIncompatibleTriggerError = (e: unknown): boolean =>
  typeof e === 'object' && e !== null && (e as any).status === 400 &&
  typeof (e as any).message === 'string' && (e as any).message.includes('incompatible with workflow trigger');

Try / catch

try {
  await api.createWorkflow(dto);
} catch (e) {
  if (isIncompatibleTriggerError(e)) {
    setFieldError('trigger', e.message);
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: POST/PUT /workflows with a trigger of AssetCreate (valid types: [AssetV1]) but a step method that only declares a non-overlapping type such as a future AssetPersonV1. The method resolves but its types do not cover the trigger's required type.

Common situations: Plugin author declares a method for a type not yet wired into triggerMap; trigger changed on an existing workflow to one the method does not support; plugin upgraded and dropped a type from a method.

Related errors


AI-assisted analysis of immich-app/immich@199723261c (2026-08-12). Data as JSON: /api/errors/5040c26639524894. Report an issue: GitHub.