instructure/canvas-lms · error · GraphQL::ExecutionError
Unable to find CommentBankItem
Error message
Unable to find CommentBankItem
What it means
DeleteCommentBankItem#resolve looks up CommentBankItem.active.find_by(id:) and raises GraphQL::ExecutionError "Unable to find CommentBankItem" when no active record matches. The lookup is also ID-prepared via relay_or_legacy_id_prepare_func, so malformed ids fail the same way.
Solutions
- Verify the id exists: CommentBankItem.active.find_by(id:) for the current user.
- Refresh the comment bank list and delete only ids currently returned.
- Ensure the id is the CommentBankItem's own relay/legacy id, not another node's.
- Treat this error as idempotent success if the item was already deleted.
Example fix
// before
deleteCommentBankItem(input: { id: staleId })
// after
const item = user.commentBankItems.find(i => i.id === id)
if (item) deleteCommentBankItem(input: { id: item.id }) Defensive patterns
Strategy: validation
Validate before calling
const item = me.commentBankItems?.nodes?.find(i => i._id === id)
if (!item) throw new SkipError('comment bank item missing') Type guard
function itemExists(items, id) { return (items || []).some(i => String(i._id ?? i.id) === String(id)); } Try / catch
try {
await deleteCommentBankItem({ id })
} catch (e) {
if (e.message.includes('Unable to find CommentBankItem')) {
refetchCommentBank(); // already deleted or wrong id
} else throw e;
} Prevention
- Refetch the user's comment bank before delete operations.
- Handle double-delete as success (idempotent UX).
- Ensure ids come from the same user's comment bank query.
When it happens
Trigger: Deleting a comment bank item with an id that doesn't exist, was already soft-deleted, belongs to another user (items are per-user), or an id string the relay/legacy prepare function can't decode to a valid record.
Common situations: Two tabs open, item already deleted in the other; user sharing ids across accounts; stale cached comment library after item removal; passing global (relay) id of the wrong node type.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- A course with that id does not exist
- ActiveRecord::RecordNotFound
- Allocation rule not found
- An assignment with that id does not exist
- Assignment not found
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/8c32b654b1c36d28.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/delete_comment_bank_item.rb:29
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
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)