langgenius/dify · error · NotChatAppError
not_chat_app
not_chat_app
Error message
App mode is invalid.
What it means
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.
Source
Thrown at api/controllers/console/explore/message.py:86
@console_ns.route(
"/installed-apps/<uuid:installed_app_id>/messages",
endpoint="installed_app_messages",
)
class MessageListApi(InstalledAppResource):
@console_ns.doc(params=query_params_from_model(MessageListQuery))
@console_ns.response(200, "Success", console_ns.models[ExploreMessageInfiniteScrollPagination.__name__])
@with_current_user
def get(self, current_user: Account, installed_app: InstalledApp):
session = db.session()
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 = MessageListQuery.model_validate(request.args.to_dict())
try:
pagination = MessageService.pagination_by_first_id(
app_model,
current_user,
args.conversation_id,
args.first_id or None,
args.limit,
session=session,
)
adapter = TypeAdapter(ExploreMessageListItem)
items = [
adapter.validate_python(MessageResponseSource(message, session=session), from_attributes=True)
for message in pagination.data
]
return ExploreMessageInfiniteScrollPagination(
limit=pagination.limit,View on GitHub (pinned to ef8544b173)
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.
Example fix
// before: always fetch messages
const msgs = await get(`/installed-apps/${id}/messages`);
// after: only for chat-family modes
const CHAT_MODES = ['chat', 'agent-chat', 'advanced-chat'];
if (CHAT_MODES.includes(app.mode)) {
const msgs = await get(`/installed-apps/${id}/messages`);
} Defensive patterns
Strategy: type-guard
Validate before calling
const CHAT_MODES = new Set(['chat', 'agent-chat', 'advanced-chat']);
function shouldFetchMessages(app) {
return CHAT_MODES.has(app.mode);
}
if (!shouldFetchMessages(app)) return; // skip messages call for non-chat apps Type guard
function isChatModeApp(app) {
return ['chat', 'agent-chat', 'advanced-chat'].includes(app?.mode);
} Try / catch
try {
return await get(messagesUrl(id));
} catch (e) {
if (e.code === 'not_chat_app') {
routeToModeSpecificView(app.mode);
return null;
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- not_completion_app
- app_unavailable
- Conversation Not Exists.
- First Message Not Exists.
- Message Not Exists.
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/4c52c093afb92051.
Report an issue: GitHub.