langgenius/dify · error · MigrationDataError

No workflow or advanced-chat apps found for the selected ten

Error message

No workflow or advanced-chat apps found for the selected tenant.

What it means

MigrationDataError raised by _prompt_app_ids when _eligible_apps_for_tenant returns an empty list. Eligible apps are those whose mode is in SUPPORTED_WIZARD_APP_MODES (workflow and advanced-chat/chatflow). If the selected tenant has none, the wizard cannot proceed.

Source

Thrown at api/commands/data_migration.py:335

    tenant_index = click.prompt("Select one source tenant by number", type=int, default=1, show_default=True)
    if tenant_index < 1 or tenant_index > len(tenants):
        raise click.ClickException(f"Selection index out of range: {tenant_index}")
    return tenants[tenant_index - 1]


def _eligible_apps_for_tenant(tenant_id: str) -> list[App]:
    return list(
        db.session.scalars(
            sa.select(App)
            .where(App.tenant_id == tenant_id, App.mode.in_(SUPPORTED_WIZARD_APP_MODES))
            .order_by(App.name.asc())
        ).all()
    )


def _prompt_app_ids(apps: list[App]) -> list[str]:
    if not apps:
        raise MigrationDataError("No workflow or advanced-chat apps found for the selected tenant.")

    _print_wizard_step("App Selection")
    click.echo("Currently supported app types: workflow and chatflow.")
    click.echo("Workflow/chatflow apps:")
    for index, app in enumerate(apps, 1):
        mode = app.mode.value if hasattr(app.mode, "value") else app.mode
        click.echo(f"{index}. {app.name} [{mode}] ({app.id})")
    app_ids = parse_index_selection(
        click.prompt("Select apps by number, comma-separated numbers, or all", default="all"),
        [app.id for app in apps],
    )
    selected_apps = [app for app in apps if app.id in set(app_ids)]
    click.echo("Selected apps:")
    for app in selected_apps:
        click.echo(f"- {app.name} ({app.id})")
    return app_ids

View on GitHub (pinned to ef8544b173)

Solutions

  1. Run `SELECT id, name, mode FROM apps WHERE tenant_id = '<id>';` to inspect available app types.
  2. Select a different source tenant that has workflow/chatflow apps.
  3. Confirm SUPPORTED_WIZARD_APP_MODES matches the app modes you expect to export.
  4. If the tenant should have eligible apps, verify the apps are not in a deleted state.

Example fix

# before - tenant has only completion apps
# SELECT mode, count(*) FROM apps WHERE tenant_id='t1' GROUP BY mode;
#  completion | 5

# after - pick tenant with workflow apps
#  workflow   | 3
#  chat       | 2
Defensive patterns

Strategy: validation

Validate before calling

from sqlalchemy import select
from models import App

def eligible_app_count(session, tenant_id: str) -> int:
    return session.scalar(
        select(func.count()).select_from(App)
        .where(App.tenant_id == tenant_id, App.mode.in_(SUPPORTED_WIZARD_APP_MODES))
    ) or 0

Type guard

def has_eligible_apps(session, tenant_id: str) -> bool:
    return session.scalars(
        select(App).where(App.tenant_id == tenant_id, App.mode.in_(SUPPORTED_WIZARD_APP_MODES)).limit(1)
    ).first() is not None

Try / catch

try:
    app_ids = _prompt_app_ids(apps)
except MigrationDataError as exc:
    click.echo(str(exc), err=True)
    raise click.Abort()

Prevention

When it happens

Trigger: Triggered when the selected tenant has zero App rows with mode in SUPPORTED_WIZARD_APP_MODES - i.e. only completion/basic apps exist, or no apps at all for that tenant.

Common situations: The tenant only contains agent or completion apps (unsupported modes), the tenant was mis-selected, or the apps were soft-deleted/archived in a way that filters them out.

Related errors


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