instructure/canvas-lms · error
can't accept
Error message
can't accept
What it means
Enrollment#accept! is the strict/banging wrapper around #accept: it calls accept and raises 'can't accept' when accept returns a falsy result, i.e. the enrollment could not be transitioned to an accepted/invited-accepted state under current rules (wrong workflow state, enrollment not invitable/accept-able, etc.).
Solutions
- Check the enrollment state first and only call accept! when acceptance is allowed (e.g. invited?/invited_state?)
- Use the non-banging enrollment.accept and handle the false return instead of raising
- Reload the enrollment before accepting to pick up concurrent state changes
- Pass accept(force: true) via the underlying method only when you intentionally need to override constraints
Example fix
// before enrollment.accept! // after enrollment.reload enrollment.accept if enrollment.invited?
Defensive patterns
Strategy: try-catch
Validate before calling
enrollment.reload raise 'not acceptable' unless enrollment.may_accept? # or check invited state enrollment.accept!
Try / catch
begin
enrollment.accept!
rescue RuntimeError => e
raise unless e.message == "can't accept"
Rails.logger.warn("enrollment #{enrollment.id} not acceptable (#{enrollment.workflow_state})")
end Prevention
- Check workflow_state allows acceptance before calling accept!
- Reload before mutating to avoid stale state
- Prefer non-banging accept and handle its boolean return in jobs
When it happens
Trigger: Calling enrollment.accept! when #accept returns false/nil — typically because the enrollment's workflow_state does not permit acceptance (e.g. already rejected/completed/deleted, not invited), or the user on the enrollment is not the one being accepted for without force.
Common situations: Self-enrollment or invitation-accept flows hitting a stale enrollment that was already rejected or deleted in another tab; background jobs accepting enrollments after the course concluded; specs accepting a factory-built enrollment that was never in invited state.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- cannot call enrollment_state on a new record
- assessor and assessee required
- association required
- can only forward one conversation at a time
- Can't update submission scores unless it's completed
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/0fc195682c37d14a.
Report an issue: GitHub.
Appendix: source
Thrown at app/models/enrollment.rb:751
STATE_RANK_HASH[state.to_s]
end
STATE_BY_DATE_RANK = ["active", %w[invited creation_pending pending_active pending_invited], "completed", "inactive", "rejected", "deleted"].freeze
STATE_BY_DATE_RANK_HASH = rank_hash(STATE_BY_DATE_RANK)
def self.state_by_date_rank_sql
@state_by_date_rank_sql ||= Arel.sql(
rank_sql(STATE_BY_DATE_RANK, "enrollment_states.state")
.sub(/^CASE/, "CASE WHEN enrollment_states.restricted_access THEN #{STATE_BY_DATE_RANK.index("inactive")}") # pretend restricted access is the same as inactive
)
end
def state_with_date_sortable
STATE_RANK_HASH[state_based_on_date.to_s]
end
def accept!
res = accept
raise "can't accept" unless res
res
end
def accept(force: false)
GuardRail.activate(:primary) do
return false unless force || invited?
if update_attribute(:workflow_state, "active")
if type == "StudentEnrollment"
Enrollment.recompute_final_score_in_singleton(user_id, course_id)
end
true
end
end
end
def reset_notifications_cacheView on GitHub (pinned to 1c9f0bb801)