{"record":{"id":"4c52c093afb92051","repo":"langgenius/dify","slug":"not-chat-app-4c52c0","errorCode":"not_chat_app","errorMessage":"App mode is invalid.","messagePattern":"App mode is invalid\\.","errorType":"error_code","errorClass":"NotChatAppError","httpStatus":400,"severity":"error","filePath":"api/controllers/console/explore/message.py","lineNumber":86,"sourceCode":"\n\n@console_ns.route(\n    \"/installed-apps/<uuid:installed_app_id>/messages\",\n    endpoint=\"installed_app_messages\",\n)\nclass MessageListApi(InstalledAppResource):\n    @console_ns.doc(params=query_params_from_model(MessageListQuery))\n    @console_ns.response(200, \"Success\", console_ns.models[ExploreMessageInfiniteScrollPagination.__name__])\n    @with_current_user\n    def get(self, current_user: Account, installed_app: InstalledApp):\n        session = db.session()\n        app_model = installed_app.app_with_session(session=session)\n        if app_model is None:\n            raise AppUnavailableError()\n\n        app_mode = AppMode.value_of(app_model.mode)\n        if app_mode not in {AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT}:\n            raise NotChatAppError()\n        args = MessageListQuery.model_validate(request.args.to_dict())\n\n        try:\n            pagination = MessageService.pagination_by_first_id(\n                app_model,\n                current_user,\n                args.conversation_id,\n                args.first_id or None,\n                args.limit,\n                session=session,\n            )\n            adapter = TypeAdapter(ExploreMessageListItem)\n            items = [\n                adapter.validate_python(MessageResponseSource(message, session=session), from_attributes=True)\n                for message in pagination.data\n            ]\n            return ExploreMessageInfiniteScrollPagination(\n                limit=pagination.limit,","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/api/controllers/console/explore/message.py#L68-L104","documentation":"HTTP 400 with error_code not_chat_app, raised by GET /installed-apps/<id>/messages when the app's mode is not in {CHAT, AGENT_CHAT, ADVANCED_CHAT}. The messages endpoint only exists for chat-family apps; completion, workflow, and other modes are rejected.","triggerScenarios":"GET /console/explore/installed-apps/<id>/messages on an installed app whose AppMode is completion, workflow, or unknown. The mode check fires after the app is loaded but before MessageService is called.","commonSituations":"UI routes all installed-app tiles to the messages view regardless of mode; app was migrated from chat to workflow; client hardcodes the messages URL.","solutions":["Branch the UI on app.mode: route CHAT/AGENT_CHAT/ADVANCED_CHAT to messages, completion to its own view, workflow to its own view.","Before calling messages, read the mode from GET /installed-apps/<id> (InstalledAppInfoResponse.mode) and skip the call for non-chat modes.","If the app should be a chat app, verify the mode was not changed by the owner.","Hide the 'message history' affordance entirely for non-chat apps."],"exampleFix":"// before: always fetch messages\nconst msgs = await get(`/installed-apps/${id}/messages`);\n\n// after: only for chat-family modes\nconst CHAT_MODES = ['chat', 'agent-chat', 'advanced-chat'];\nif (CHAT_MODES.includes(app.mode)) {\n  const msgs = await get(`/installed-apps/${id}/messages`);\n}","handlingStrategy":"type-guard","validationCode":"const CHAT_MODES = new Set(['chat', 'agent-chat', 'advanced-chat']);\nfunction shouldFetchMessages(app) {\n  return CHAT_MODES.has(app.mode);\n}\nif (!shouldFetchMessages(app)) return; // skip messages call for non-chat apps","typeGuard":"function isChatModeApp(app) {\n  return ['chat', 'agent-chat', 'advanced-chat'].includes(app?.mode);\n}","tryCatchPattern":"try {\n  return await get(messagesUrl(id));\n} catch (e) {\n  if (e.code === 'not_chat_app') {\n    routeToModeSpecificView(app.mode);\n    return null;\n  }\n  throw e;\n}","preventionTips":["Branch UI flows on app.mode before hitting mode-specific endpoints.","Re-read mode after app re-install or owner config changes.","Hide the messages tab for completion/workflow apps."],"tags":["rest-api","explore","app-mode","message","validation","dify"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}