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

custom grade status not found

Error message

custom grade status not found

What it means

This error is raised by the UpsertCustomGradeStatus GraphQL mutation when resolving fails with ActiveRecord::RecordNotFound. It means the custom_grade_status record the caller attempted to update (by id) does not exist, and the mutation converts that low-level exception into a user-facing GraphQL::ExecutionError.

Solutions

  1. Verify the custom grade status id exists (CustomGradeStatus.exists?(id)) before calling the mutation
  2. Check you are hitting the correct root account/shard where the record lives
  3. Re-fetch the list of custom grade statuses via the API to get fresh ids
  4. Handle the error in the client by treating it as a deleted resource and re-syncing

Example fix

// before
updateCustomGradeStatus({ id: "17", name: "Late" })
// after
const status = customGradeStatuses.find(s => s.id === "17")
if (status) await updateCustomGradeStatus({ id: status.id, name: "Late" })
Defensive patterns

Strategy: try-catch

Validate before calling

const exists = customGradeStatuses.some(s => s.id === inputId)
if (!exists) throw new Error('custom grade status ' + inputId + ' not found')

Try / catch

try {
  const res = await client.mutate(UPSERT_CUSTOM_GRADE_STATUS, { id })
} catch (e) {
  if (e.message === 'custom grade status not found') {
    await refetchStatuses() // treat as deleted, re-sync
  } else throw e
}

Prevention

When it happens

Trigger: Calling the upsertCustomGradeStatus mutation with input whose :id refers to a CustomGradeStatus that has been deleted, belongs to a different course/root account (wrong shard), or whose id was mistyped, so the record lookup raises RecordNotFound inside resolve.

Common situations: Stale client caches referencing a deleted status; calling the mutation on a different shard than where the record lives; passing an id from a non-root-account context; scripts re-running upserts after cleanup tasks removed the record.

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/fe4ba7d7aced1bf9. Report an issue: GitHub.

Appendix: source

Thrown at app/graphql/mutations/upsert_custom_grade_status.rb:50

      required_permission = custom_grade_status.new_record? ? :create : :update
      unless custom_grade_status.grants_right?(current_user, session, required_permission)
        raise GraphQL::ExecutionError, I18n.t("Insufficient permissions")
      end

      if custom_grade_status.new_record?
        InstStatsd::Statsd.distributed_increment("custom_grade_status.graphql.create")
      else
        InstStatsd::Statsd.distributed_increment("custom_grade_status.graphql.update")
      end

      if custom_grade_status.update(name: input[:name], color: input[:color])
        { custom_grade_status: }
      else
        errors_for(custom_grade_status)
      end
    rescue ActiveRecord::RecordNotFound
      raise GraphQL::ExecutionError, "custom grade status not found"
    end
  end
end

View on GitHub (pinned to 1c9f0bb801)