instructure/canvas-lms · error · GraphQL::ExecutionError
Unable to delete CommentBankItem
Error message
Unable to delete CommentBankItem
What it means
After authorization succeeds, DeleteCommentBankItem calls record.destroy; if destroy returns false (the model refused to delete, typically due to a before_destroy callback aborting or validation-adjacent failure), the mutation raises "Unable to delete CommentBankItem". Unlike the not-found case, the record exists but could not be removed.
Solutions
- Check CommentBankItem model callbacks (before_destroy) for abort conditions and logs for the actual reason.
- Retry the deletion; transient DB issues can make destroy return false.
- Inspect Rails logs around the mutation for suppressed errors during destroy.
- As an admin, verify no shard/replica lag is causing the record state to conflict.
Example fix
// before
if record.destroy
{ comment_bank_item_id: record.id }
else
raise GraphQL::ExecutionError, "Unable to delete CommentBankItem"
end
// after
if record.destroy
{ comment_bank_item_id: record.id }
else
raise GraphQL::ExecutionError, record.errors.full_messages.to_sentence.presence || "Unable to delete CommentBankItem"
end Defensive patterns
Strategy: try-catch
Try / catch
try {
await deleteCommentBankItem({ id })
} catch (e) {
if (e.message.includes('Unable to delete CommentBankItem')) {
retryWithBackoff(() => deleteCommentBankItem({ id }))
.catch(() => reportServerError('comment bank delete failed'));
} else throw e;
} Prevention
- Retry transient delete failures with backoff.
- Check server logs for before_destroy aborts when it reproduces.
- Avoid concurrent edits/deletes of the same comment bank item.
When it happens
Trigger: Calling deleteCommentBankItem on an item whose destroy callback aborts; database constraint or hook preventing deletion; concurrent modification making destroy fail.
Common situations: Item referenced elsewhere and a before_destroy guard aborts; DB replication/constraint issue; plugin or shard-level callback raising silently and returning false.
Related errors
- and cannot be used together
- and cannot be used together
- A course with that id does not exist
- A maximum of 50 assessees can be provided at once
- A maximum of 50 assessors can be provided at once
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/91aa632da5f30a97.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/delete_comment_bank_item.rb:37
#
class Mutations::DeleteCommentBankItem < Mutations::BaseMutation
graphql_name "DeleteCommentBankItem"
argument :id, ID, required: true, prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("CommentBankItem")
field :comment_bank_item_id, ID, null: false
def resolve(input:)
record = CommentBankItem.active.find_by(id: input[:id])
raise GraphQL::ExecutionError, I18n.t("Unable to find CommentBankItem") if record.nil?
verify_authorized_action!(record, :delete)
context[:deleted_models][:comment_bank_item] = record
if record.destroy
{ comment_bank_item_id: record.id }
else
raise GraphQL::ExecutionError, I18n.t("Unable to delete CommentBankItem")
end
end
def self.comment_bank_item_id_log_entry(_entry, context)
context[:deleted_models][:comment_bank_item]
end
end
View on GitHub (pinned to 1c9f0bb801)