langgenius/dify · error · NotChatAppError

not_chat_app

not_chat_app

Error message

App mode is invalid.

What it means

Raised by ChatApi.post when AppMode.value_of(app_model.mode) is not in {CHAT, AGENT_CHAT, ADVANCED_CHAT}. The chat-messages endpoint only serves chat-family apps; completion, workflow, and generator apps must use their own endpoints. Returns HTTP 400 with error_code 'not_chat_app' with description 'App mode is invalid.'

Source

Thrown at api/controllers/console/explore/completion.py:189


@console_ns.route(
    "/installed-apps/<uuid:installed_app_id>/chat-messages",
    endpoint="installed_app_chat_completion",
)
class ChatApi(InstalledAppResource):
    @console_ns.expect(console_ns.models[ChatMessagePayload.__name__])
    @console_ns.response(200, "Success")
    @with_current_user
    @with_session
    @model_validate(ChatMessagePayload)
    def post(self, req_data: ChatMessagePayload, session: Session, current_user: Account, installed_app: InstalledApp):
        app_model = installed_app.app_with_session(session=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()

        args = req_data.model_dump(exclude_none=True)

        args["auto_generate_name"] = False

        installed_app.last_used_at = naive_utc_now()
        db.session.commit()

        try:
            # Eagerly validate conversation to avoid hanging on invalid conversation_id
            if req_data.conversation_id:
                ConversationService.get_conversation(
                    app_model=app_model,
                    conversation_id=req_data.conversation_id,
                    user=current_user,
                    session=session,
                )

View on GitHub (pinned to ef8544b173)

Solutions

  1. Use /console/installed-apps/<id>/completion-messages for completion (text-generation) apps.
  2. Inspect the installed app's mode and branch the endpoint before calling.
  3. Confirm the app's intended mode in Studio.
  4. If you need a chat experience, install a chat-template app instead.

Example fix

// before: always uses chat-messages
const url = `/installed-apps/${id}/chat-messages`

// after: route by mode
const url = ['chat','agent-chat','advanced-chat'].includes(appMode)
  ? `/installed-apps/${id}/chat-messages`
  : `/installed-apps/${id}/completion-messages`
Defensive patterns

Strategy: validation

Validate before calling

// Route by app mode before posting to chat-messages.
function isChatMode(mode) {
  return ['chat','agent-chat','advanced-chat'].includes(mode);
}
if (!isChatMode(installedApp.app_mode)) { redirectToCompletionEndpoint(installedApp); }

Type guard

function isChatApp(entry) {
  return ['chat','agent-chat','advanced-chat'].includes(entry?.app_mode);
}

Try / catch

try {
  await postChat(id, payload);
} catch (err) {
  if (err.code === 'not_chat_app') {
    await postCompletion(id, payload);
  } else { throw err; }
}

Prevention

When it happens

Trigger: POST /console/installed-apps/<id>/chat-messages against an installed app whose mode is COMPLETION, WORKFLOW, or GENERATOR. Happens when the client routes a non-chat installed app to the chat endpoint.

Common situations: Frontend assumes every installed app is a chat app; user installed a completion-template app but the UI sends to chat-messages; app mode was changed in Studio after the client cached the type.

Related errors


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