instructure/canvas-lms · error · ConversationsHelper::Error
not for this conversation
Error message
not for this conversation
What it means
Rescue translator: when building a conversation message, an included_message id that does not belong to the target conversation raises ConversationsHelper::InvalidMessageForConversationError, which is re-raised as a bad_request ConversationsHelper::Error with message 'not for this conversation'.
Solutions
- Only pass included_messages ids that appear under the same conversation_id.
- Re-fetch the conversation's messages and rebuild the included_messages list before the call.
- Catch ConversationsHelper::Error with attribute included_messages and prompt the user to reselect attachments.
- Verify message ids via the conversation messages endpoint before attaching.
Example fix
// before included_messages: [123, 456] // 456 belongs to another conversation // after included_messages: conversation.conversation_messages.where(id: [123,456]).pluck(:id)
Defensive patterns
Strategy: validation
Validate before calling
msg_ids = conversation.conversation_messages.pluck(:id) bad = params[:included_messages] - msg_ids.map(&:to_i) raise ArgumentError, 'included_messages not in conversation' if bad.any?
Try / catch
begin
add_message(...)
rescue ConversationsHelper::Error => e
return render json: { error: e.message, attribute: 'included_messages' }, status: :bad_request
end Prevention
- Build included_messages only from the same conversation's messages
- Refresh message ids from the server before forwarding
- Never mix ids across conversations in one request
When it happens
Trigger: Conversations API call passing included_messages[] referencing message ids whose conversation_id differs from the conversation being replied to (e.g. forwarding/multimedia attach with stale or mixed ids).
Common situations: Client merges messages from two threads; UI caches message ids after the conversation was deleted/merged; id typo from manual API testing.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- not a participant
- can only forward one conversation at a time
- can't add participants if there are no messages
- can't add participants to a private conversation
- Course concluded, unable to send messages
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/1d0ebfe5a4029d73.
Report an issue: GitHub.
Appendix: source
Thrown at app/helpers/conversations_helper.rb:142
message = Conversation.build_message(*message_args)
message.id = 0
message.conversation_id = conversation.conversation_id
message.created_at = Time.now.utc
{ message:, recipients_count: existing_participant_ids.size, status: :accepted }
end
elsif conversation.should_process_immediately?
message = conversation.process_new_message(message_args, recipients, message_ids, tags)
{ message:, recipients_count: recipients ? recipients.count : 0, status: :ok }
else
conversation.delay(strand: "add_message_#{conversation.global_conversation_id}").process_new_message(message_args, recipients, message_ids, tags)
message = Conversation.build_message(*message_args)
message.id = 0
message.conversation_id = conversation.conversation_id
message.created_at = Time.now.utc
{ message:, recipients_count: recipients ? recipients.count : 0, status: :accepted }
end
rescue ConversationsHelper::InvalidMessageForConversationError
raise ConversationsHelper::Error.new(message: I18n.t("not for this conversation"), status: :bad_request, attribute: "included_messages")
rescue ConversationsHelper::InvalidMessageParticipantError
raise ConversationsHelper::Error.new(message: I18n.t("not a participant"), status: :bad_request, attribute: "included_messages")
end
def contexts_for(audience, context_tags)
result = { courses: {}, groups: {} }
return result if audience.empty?
context_tags.each do |tag|
next unless tag =~ /\A(course|group)_(\d+)\z/
result[:"#{$1}s"][$2.to_i] = []
end
if audience.size == 1 && include_private_conversation_enrollments
enrollments = Shard.partition_by_shard(result[:courses].keys) do |course_ids|
next unless audience.first.associated_shards.include?(Shard.current)
View on GitHub (pinned to 1c9f0bb801)