instructure/canvas-lms · error · GraphQL::ExecutionError

Rubric not found: #

Error message

Rubric not found: #{input[:id]}

What it means

UpdateRubricArchivedState mutation rescues ActiveRecord::RecordNotFound from Rubric.find and re-raises as a GraphQL::ExecutionError including the offending id. Rubric.find raises RecordNotFound when no rubric with that primary key exists.

Solutions

  1. Confirm the rubric id exists via a rubric query before mutating
  2. Use the rubric's own id, not the assignment's rubric_association id
  3. Handle the GraphQL error in the client and refresh the rubric list
  4. Check the rubric wasn't deleted or moved to another account

Example fix

// before
updateRubricArchivedState(input: {id: association.rubric_association_id, archived: true})
// after
updateRubricArchivedState(input: {id: association.rubric_id, archived: true})
Defensive patterns

Strategy: try-catch

Validate before calling

const { rubric } = await gql(rubricQuery, {id}); if (!rubric) skipArchive();

Type guard

const isRubric = (r) => r != null && typeof r.id !== 'undefined' && r.__typename === 'Rubric'

Try / catch

try { await gql(updateRubricArchivedStateMutation, {id, archived}) } catch (e) { if (/Rubric not found/.test(e.message)) { refreshRubricList(); return; } throw e }

Prevention

When it happens

Trigger: Calling updateRubricArchivedState with an id of a deleted rubric, a numeric id that doesn't exist, or an id belonging to another root account/shard.

Common situations: UI caching rubric IDs from a removed course; user archiving a rubric that another teacher already deleted; passing a rubric association id instead of the rubric id.

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


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

Appendix: source

Thrown at app/graphql/mutations/update_rubric_archived_state.rb:30

# 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::UpdateRubricArchivedState < Mutations::BaseMutation
  argument :archived, Boolean, required: true
  argument :id, ID, required: true

  field :rubric, Types::RubricType, null: true
  def resolve(input:)
    begin
      @rubric = Rubric.find(input[:id])
    rescue ActiveRecord::RecordNotFound
      raise GraphQL::ExecutionError, "Rubric not found: #{input[:id]}"
    end
    requested_permission = input[:archived] ? :archive : :unarchive
    verify_authorized_action!(@rubric, requested_permission)
    if input[:archived]
      @rubric.archive
    else
      @rubric.unarchive
    end
    { rubric: @rubric }
  end
end

View on GitHub (pinned to 1c9f0bb801)