{"record":{"id":"710e7786b5d46d0b","repo":"langgenius/dify","slug":"invalid-param","errorCode":"invalid_param","errorMessage":"rating cannot be None when feedback not exists","messagePattern":"rating cannot be None when feedback not exists","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"warning","filePath":"api/controllers/console/app/message.py","lineNumber":486,"sourceCode":"def _update_message_feedback(*, session: Session, current_user: Account, app_model: App):\n    args = MessageFeedbackPayload.model_validate(console_ns.payload)\n\n    message_id = args.message_id\n\n    message = session.scalar(select(Message).where(Message.id == message_id, Message.app_id == app_model.id).limit(1))\n\n    if not message:\n        raise NotFound(\"Message Not Exists.\")\n\n    feedback = message.admin_feedback_with_session(session=session)\n\n    if not args.rating and feedback:\n        session.delete(feedback)\n    elif args.rating and feedback:\n        feedback.rating = FeedbackRating(args.rating)\n        feedback.content = args.content\n    elif not args.rating and not feedback:\n        raise ValueError(\"rating cannot be None when feedback not exists\")\n    else:\n        rating_value = args.rating\n        if rating_value is None:\n            raise ValueError(\"rating is required to create feedback\")\n        feedback = MessageFeedback(\n            app_id=app_model.id,\n            conversation_id=message.conversation_id,\n            message_id=message.id,\n            rating=FeedbackRating(rating_value),\n            content=args.content,\n            from_source=FeedbackFromSource.ADMIN,\n            from_account_id=current_user.id,\n        )\n        session.add(feedback)\n\n    session.commit()\n\n    return SimpleResultResponse(result=\"success\").model_dump(mode=\"json\")","sourceCodeStart":468,"sourceCodeEnd":504,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/api/controllers/console/app/message.py#L468-L504","documentation":"ValueError (code=invalid_param) raised in _update_message_feedback (message.py:486) when the client sends no rating AND there is no existing feedback to delete. The handler treats a missing rating as 'delete existing feedback'; with nothing to delete, the request is contradictory. Flask surfaces this as a 400.","triggerScenarios":"POST /console/api/apps/<app_id>/feedbacks with no rating field (or rating=null) for a message that has no prior feedback record.","commonSituations":"Client sending a 'clear feedback' request for a message the user never rated; toggling a like/dislike off before it was ever set; UI bug omitting rating on first submit.","solutions":["If you want to rate, include rating='like' or rating='dislike' in the payload.","If you want to clear feedback, only call this when a feedback record already exists (track prior state client-side).","Treat the absence of existing feedback as a no-op on the client rather than sending a delete."],"exampleFix":"// before\nPOST /feedbacks  { \"message_id\": \"...\" }\n// after\nPOST /feedbacks  { \"message_id\": \"...\", \"rating\": \"like\" }","handlingStrategy":"validation","validationCode":"// Only send delete (no rating) when a feedback record exists client-side\nfunction buildFeedbackPayload(message, currentRating) {\n  if (!message.rating && !currentRating) {\n    // nothing to clear; do not call\n    return null;\n  }\n  return { message_id: message.id, rating: currentRating };\n}","typeGuard":null,"tryCatchPattern":"try {\n  await submitFeedback(appId, payload);\n} catch (e) {\n  if (e.code === 'invalid_param' && /rating cannot be none/i.test(e.message)) {\n    // no existing feedback to delete; treat as no-op\n  } else throw e;\n}","preventionTips":["Track whether a feedback record exists before sending a 'clear' request.","Always include rating on the first feedback submission.","Treat 'no rating + no existing feedback' as a client-side no-op."],"tags":["validation","feedback","rating","invalid-param"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}