{"record":{"id":"583e7a3586eef0e4","repo":"langgenius/dify","slug":"first-message-not-exists","errorCode":null,"errorMessage":"First Message Not Exists.","messagePattern":"First Message Not Exists\\.","errorType":"http","errorClass":"NotFound","httpStatus":404,"severity":"error","filePath":"api/controllers/console/explore/message.py","lineNumber":111,"sourceCode":"                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,\n                has_more=pagination.has_more,\n                data=items,\n            ).model_dump(mode=\"json\")\n        except ConversationNotExistsError:\n            raise NotFound(\"Conversation Not Exists.\")\n        except FirstMessageNotExistsError:\n            raise NotFound(\"First Message Not Exists.\")\n\n\n@console_ns.route(\n    \"/installed-apps/<uuid:installed_app_id>/messages/<uuid:message_id>/feedbacks\",\n    endpoint=\"installed_app_message_feedback\",\n)\nclass MessageFeedbackApi(InstalledAppResource):\n    @console_ns.expect(console_ns.models[MessageFeedbackPayload.__name__])\n    @console_ns.response(200, \"Feedback submitted successfully\", console_ns.models[ResultResponse.__name__])\n    @with_current_user\n    @model_validate(MessageFeedbackPayload)\n    def post(\n        self, req_data: MessageFeedbackPayload, current_user: Account, installed_app: InstalledApp, message_id: UUID\n    ):\n        app_model = installed_app.app_with_session(session=db.session())\n        if app_model is None:\n            raise AppUnavailableError()\n","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/api/controllers/console/explore/message.py#L93-L129","documentation":"HTTP 404 raised by GET /installed-apps/<id>/messages when MessageService raises FirstMessageNotExistsError. The first_id query parameter (the pagination anchor) does not reference a real message in the conversation.","triggerScenarios":"GET messages with ?first_id=<mid> where <mid> is not a valid message id within the conversation, has been deleted, or belongs to a different conversation. Used as the cursor for infinite-scroll pagination backward/forward.","commonSituations":"Pagination cursor from a stale page; message was deleted between page fetches; first_id concatenated/encoded incorrectly; user jumped to a deep link whose anchor message is gone.","solutions":["On 404 with this message, discard the stored first_id cursor and re-fetch the first page.","Encode first_id exactly as returned by the previous response (UUID string, no truncation).","If deep-linking, validate the message id is still present before scrolling to it.","Handle message-deletion events from the realtime channel to invalidate affected cursors."],"exampleFix":"// before: keep paging from a cursor that may be dead\nconst next = await get(messagesUrl({ first_id: cursor }));\n\n// after: reset cursor on 'First Message Not Exists'\ntry {\n  const next = await get(messagesUrl({ first_id: cursor }));\n} catch (e) {\n  if (e.status === 404) { cursor = null; const next = await get(messagesUrl({})); }\n  else throw e;\n}","handlingStrategy":"try-catch","validationCode":"// Drop pagination cursor before calling if it looks malformed\nfunction validMessageId(v) {\n  return typeof v === 'string' && /^[0-9a-fA-F-]{36}$/.test(v);\n}\nif (!validMessageId(firstId)) firstId = null;","typeGuard":"function isLikelyValidFirstId(value) {\n  return typeof value === 'string' && /^[0-9a-fA-F-]{36}$/.test(value);\n}","tryCatchPattern":"try {\n  return await get(messagesUrl(id, { first_id: cursor }));\n} catch (e) {\n  if (e.status === 404 && /First Message Not Exists/.test(e.message)) {\n    cursor = null;\n    return get(messagesUrl(id, {})); // first page\n  }\n  throw e;\n}","preventionTips":["Reset the cursor on 404 and re-fetch the first page.","Invalidate cursors when message-deletion events arrive.","Encode first_id exactly as returned (full UUID, no truncation)."],"tags":["rest-api","explore","not-found","pagination","message","dify"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}