langgenius/dify · error · NotFound

Trigger not found

Error message

Trigger not found

What it means

Raised by POST /apps/{app_id}/trigger-enable when no AppTrigger row matches (trigger_id, current_tenant_id, app_id). The trigger must belong to the caller's tenant and the URL's app. Returned via flask_restx NotFound (HTTP 404).

Source

Thrown at api/controllers/console/app/workflow_trigger.py:194

    @with_current_tenant_id
    @get_app_model(mode=AppMode.WORKFLOW)
    @model_validate(ParserEnable)
    def post(self, req_data: ParserEnable, current_tenant_id: str, app_model: App):
        """Update app trigger (enable/disable)"""

        trigger_id = req_data.trigger_id
        with sessionmaker(db.engine, expire_on_commit=False).begin() as session:
            # Find the trigger using select
            trigger = session.execute(
                select(AppTrigger).where(
                    AppTrigger.id == trigger_id,
                    AppTrigger.tenant_id == current_tenant_id,
                    AppTrigger.app_id == app_model.id,
                )
            ).scalar_one_or_none()

            if not trigger:
                raise NotFound("Trigger not found")

            # Update status based on enable_trigger boolean
            trigger.status = AppTriggerStatus.ENABLED if req_data.enable_trigger else AppTriggerStatus.DISABLED

        # Add computed icon field
        url_prefix = dify_config.CONSOLE_API_URL + "/console/api/workspaces/current/tool-provider/builtin/"
        if trigger.trigger_type == "trigger-plugin":
            trigger.icon = url_prefix + trigger.provider_name + "/icon"  # type: ignore
        else:
            trigger.icon = ""  # type: ignore

        return dump_response(WorkflowTriggerResponse, trigger)

View on GitHub (pinned to ef8544b173)

Solutions

  1. Refresh the trigger list via GET /apps/{app_id}/triggers and use a current trigger_id.
  2. Confirm the trigger belongs to the same tenant and app as the URL before toggling.
  3. If the trigger was removed, recreate it through the workflow studio Trigger panel.
Defensive patterns

Strategy: validation

Validate before calling

const triggers = await get(`/apps/${appId}/triggers`);
const ok = triggers.data.some(t => t.id === triggerId);
if (!ok) { /* do not POST trigger-enable */ }

Try / catch

try {
  await post(`/apps/${appId}/trigger-enable`, { trigger_id: triggerId, enable_trigger: val });
} catch (e) {
  if (e.code === 404 && /trigger not found/i.test(e.message)) {
    // refresh trigger list, drop stale id
  } else { throw e; }
}

Prevention

When it happens

Trigger: POST /console/api/apps/{app_id}/trigger-enable with body {trigger_id, enable_trigger} where trigger_id does not exist, belongs to another tenant, belongs to another app, or was deleted.

Common situations: Stale trigger_id in the UI after the trigger was removed; cross-tenant or cross-app reference; enabling a trigger on the wrong app after a copy; trigger row hard-deleted by a cleanup job.

Related errors


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/7bf9aa0e7f5d7662. Report an issue: GitHub.