langgenius/dify · error · NotChatAppError

not_chat_app

not_chat_app

Error message

App mode is invalid.

What it means

NotChatAppError (HTTP 400, code 'not_chat_app') is raised in ConversationListApi.get when the app_model's mode is not CHAT, AGENT_CHAT, or ADVANCED_CHAT. Conversations only exist for chat-style apps; requesting conversations for a completion/workflow/generator app is invalid.

Source

Thrown at api/controllers/console/explore/conversation.py:62

    SimpleConversation,
)


@console_ns.route(
    "/installed-apps/<uuid:installed_app_id>/conversations",
    endpoint="installed_app_conversations",
)
class ConversationListApi(InstalledAppResource):
    @console_ns.doc(params=query_params_from_model(ConversationListQuery))
    @console_ns.response(200, "Success", console_ns.models[ConversationInfiniteScrollPagination.__name__])
    @with_current_user
    def get(self, current_user: Account, installed_app: InstalledApp):
        app_model = installed_app.app_with_session(session=db.session())
        if app_model is None:
            raise AppUnavailableError()
        app_mode = AppMode.value_of(app_model.mode)
        if app_mode not in {AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT}:
            raise NotChatAppError()

        raw_args: dict[str, Any] = {
            "last_id": request.args.get("last_id"),
            "limit": request.args.get("limit", default=20, type=int),
            "pinned": request.args.get("pinned"),
        }
        if raw_args["last_id"] is None:
            raw_args["last_id"] = None
        pinned_value = raw_args["pinned"]
        if isinstance(pinned_value, str):
            raw_args["pinned"] = pinned_value == "true"
        args = ConversationListQuery.model_validate(raw_args)

        try:
            with sessionmaker(db.engine).begin() as session:
                pagination = WebConversationService.pagination_by_last_id(
                    session=session,
                    app_model=app_model,

View on GitHub (pinned to ef8544b173)

Solutions

  1. Check the app's mode via GET /console/explore/installed-apps/<id> and only show conversation UI for chat-mode apps.
  2. If the app mode changed, update the client to reflect the new mode — non-chat apps have no conversations.
  3. Contact the app owner if the mode change was unexpected.
Defensive patterns

Strategy: validation

Validate before calling

function isChatMode(mode) {
  return ['chat', 'agent-chat', 'advanced-chat'].includes(mode);
}
if (!isChatMode(installedApp.mode)) {
  // do not show conversation list for non-chat apps
}

Type guard

function isChatApp(app) {
  return ['chat', 'agent-chat', 'advanced-chat'].includes(app.mode);
}

Try / catch

try {
  await listConversations(installedAppId);
} catch (e) {
  if (e.code === 'not_chat_app') {
    // hide conversation UI — this app type has no conversations
    hideConversationList();
  }
}

Prevention

When it happens

Trigger: GET /console/explore/installed-apps/<installed_app_id>/conversations where the installed app mode is COMPLETION, WORKFLOW, or GENERATOR. The client attempted to list conversations for an app type that does not have conversations.

Common situations: The app was switched from chat to another mode by its owner; the frontend incorrectly shows a conversation list UI for a non-chat app; a stale bookmark or API call targets the wrong endpoint.

Related errors


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