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
- Verify the custom grade status id exists (CustomGradeStatus.exists?(id)) before calling the mutation
- Check you are hitting the correct root account/shard where the record lives
- Re-fetch the list of custom grade statuses via the API to get fresh ids
- 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
- Re-fetch status lists instead of caching ids across sessions
- Confirm shard/root account before cross-account upserts
- Handle RecordNotFound as a soft-delete signal in the client
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)