instructure/canvas-lms · error

can only forward one conversation at a time

Error message

can only forward one conversation at a time

What it means

Conversation#add_message (and forwarding flow) validates forwarded messages come from exactly one conversation. After filtering to forwardable messages, if the resulting distinct conversation_ids count is not 1, this error is raised to prevent mixing messages from multiple conversations in one forward.

Solutions

  1. Ensure the forwarded message IDs all belong to a single conversation before calling add_message
  2. Filter the selection in the UI so multi-conversation selections are forwarded in separate calls
  3. Check messages are forwardable? first; if none are, skip forwarding instead of passing empty/mixed IDs

Example fix

// before
conversation.add_message(user, 'fyi', forwarded_message_ids: [1, 2, 77])
// after
ids = [1, 2] # all from conversation 42
conversation.add_message(user, 'fyi', forwarded_message_ids: ids)
# forward messages from conversation 77 in a separate call
Defensive patterns

Strategy: validation

Validate before calling

ids = forwarded_message_ids.map(&:to_i)
convs = ConversationMessage.where(id: ids).select(&:forwardable?).map(&:conversation_id).uniq
raise ArgumentError, 'forward messages from exactly one conversation' unless convs.size == 1

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Calling Conversation#add_message with options[:forwarded_message_ids] containing messages from more than one conversation, or IDs that resolve to zero forwardable messages (conversation_ids.size == 0).

Common situations: UI code letting users multi-select messages across conversations then forwarding them together; stale/expired message IDs that are no longer forwardable so the filtered set is empty; passing raw arrays of mixed IDs from a client.

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


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/73f17ac0becfe5f4. Report an issue: GitHub.

Appendix: source

Thrown at app/models/conversation.rb:355

  def self.build_message(current_user, body, options = {})
    message = ConversationMessage.new
    message.author_id = current_user.id
    message.body = body
    message.generated = options[:generated] || false
    message.automated = options[:automated] || false
    if options[:root_account_id]
      message.context_type = "Account"
      message.context_id = options[:root_account_id]
    end

    message.asset = options[:asset]
    message.attachment_ids = options[:attachment_ids] if options[:attachment_ids].present?
    message.media_comment = options[:media_comment] if options[:media_comment].present?
    if options[:forwarded_message_ids].present?
      messages = ConversationMessage.where(id: options[:forwarded_message_ids].map(&:to_i))
      conversation_ids = messages.select(&:forwardable?).map(&:conversation_id).uniq
      raise "can only forward one conversation at a time" if conversation_ids.size != 1
      raise "user doesn't have permission to forward these messages" unless current_user.all_conversations.where(conversation_id: conversation_ids.first).exists?

      # TODO: optimize me
      message.forwarded_message_ids = messages.map(&:id).join(",")
    end

    # Grab snapshot hash of user's inbox settings and save to message (If FF is enabled)
    if Account.site_admin.feature_enabled?(:inbox_settings)
      message.inbox_settings_ooo_hash = Inbox::InboxService.inbox_settings_ooo_hash(user_id: current_user.id, root_account_id: options[:root_account_id])
    end

    message
  end

  def preload_users_and_context_codes
    users = User.where(id: conversation_participants.map(&:user_id)).pluck(:id, :updated_at).map do |id, updated_at|
      User.send(:instantiate, "id" => id, "updated_at" => updated_at)
    end

View on GitHub (pinned to 1c9f0bb801)