instructure/canvas-lms · error · GraphQL::ExecutionError
All ConversationMessages must exist within the same…
Error message
All ConversationMessages must exist within the same Conversation
What it means
GraphQL::ExecutionError raised in Mutations::DeleteConversationMessages#resolve when the supplied message ids belong to more than one Conversation. The mutation only supports deleting messages within a single conversation, so it validates that all preloaded messages map to one conversation before checking participant permissions.
Solutions
- Group ids by conversation and issue one mutation call per conversation
- Validate client-side that all selected ids come from the same conversation before invoking the mutation
- Fetch messages first and check conversation_id uniformity before calling the mutation
- Use the batch_conversation_messages delete API if cross-conversation deletion is needed
Example fix
// before deleteConversationMessages(ids: [101, 202, 303]) // ids span 2 conversations // after await deleteConversationMessages(ids: [101, 202]) await deleteConversationMessages(ids: [303])
Defensive patterns
Strategy: validation
Validate before calling
const convIds = new Set(ids.map(id => getMessage(id).conversationId))
if (convIds.size > 1) throw new Error('ids must belong to one conversation') Prevention
- Group ids by conversation before batching
- Constrain multi-select UI to a single conversation thread
- Refresh selection state after any conversation change
When it happens
Trigger: Calling deleteConversationMessages with input[:ids] where messages.map(&:conversation).uniq.length > 1 — i.e. mixing message ids from two or more different conversations in one request.
Common situations: Client UIs that let users select messages across conversation threads before deleting; batch scripts reusing id lists; stale selections in the UI after conversations were merged or the user switched threads.
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
- A maximum of 50 assessees can be provided at once
- A maximum of 50 assessors can be provided at once
- An unexpected error occurred while grading.
- An unexpected error occurred while submitting feedback.
- Anonymous assignments must be manually posted
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/16b7d5ec84b52e23.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/delete_conversation_messages.rb:36
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
class Mutations::DeleteConversationMessages < Mutations::BaseMutation
graphql_name "DeleteConversationMessages"
# input arguments
argument :ids, [ID], required: true, prepare: GraphQLHelpers.relay_or_legacy_ids_prepare_func("ConversationMessage")
field :conversation_message_ids, [ID], null: false
def resolve(input:)
if current_user.account.root_account.feature_enabled?(:restrict_student_access)
raise GraphQL::ExecutionError, "Insufficient permissions"
end
messages = ConversationMessage.preload(:conversation).find(input[:ids])
if messages.map(&:conversation).uniq.length > 1
raise GraphQL::ExecutionError, "All ConversationMessages must exist within the same Conversation"
end
participant_record = current_user.all_conversations.find_by(conversation_id: messages.first.conversation.id)
raise GraphQL::ExecutionError, "Insufficient permissions" if participant_record.nil?
participant_record.remove_messages(*messages)
context[:deleted_models] = { conversation_messages: {} }
messages.each { |message| context[:deleted_models][:conversation_messages][message.id.to_s] = message }
{ conversation_message_ids: input[:ids] }
rescue ActiveRecord::RecordInvalid => e
errors_for(e.record)
rescue ActiveRecord::RecordNotFound
raise GraphQL::ExecutionError, "Unable to find ConversationMessage"
end
def self.conversation_message_ids_log_entry(entry, context)
context[:deleted_models][:conversation_messages][entry]
endView on GitHub (pinned to 1c9f0bb801)