instructure/canvas-lms · warning
Canvas Career permission overrides failed: #
Error message
Canvas Career permission overrides failed: #{e.message} What it means
A fallback warning in lib/permissions.rb when applying Canvas Career permission overrides raises any exception. The code rescues the error, logs it with e.message, and returns the un-overridden permissions, so Canvas Career-specific permission customization silently degrades to base permissions.
Solutions
- Check the Rails log for the full exception (use the timestamp to find the backtrace; the warning only shows e.message).
- Verify Canvas Career feature flag / account settings match the career data present; disable the flag if career data is not provisioned.
- Fix the raising code path in the career permission override block (nil-guard missing associations or malformed permission defs).
- If permissions are wrong in behavior, note that this rescue swallows overrides — confirm base permissions are safe before ignoring the warning.
Example fix
// before
rescue => e
Rails.logger.warn("Canvas Career permission overrides failed: #{e.message}")
// after
rescue => e
Rails.logger.warn("Canvas Career permission overrides failed: #{e.message}")
Rails.logger.warn(e.backtrace.join("\n")) if Rails.env.development?
Canvas::Errors.capture(e) Defensive patterns
Strategy: try-catch
Validate before calling
if @context.respond_to?(:career_data?) && @context.career_data? # safe to attempt career overrides end
Type guard
def career_permission_context?(context) context.is_a?(Account) && context.career_learning? && context.respond_to?(:career_roles) rescue NoMethodError false end
Try / catch
begin
permissions_with_overrides = apply_career_overrides(permissions)
rescue NoMethodError, ActiveRecord::StatementInvalid => e
Rails.logger.warn("Canvas Career permission overrides failed: #{e.class}: #{e.message}")
Canvas::Errors.capture(e)
permissions # fall back to base permissions
end Prevention
- Keep Canvas Career feature flag state in sync with career data provisioning
- Nil-guard career associations inside override blocks
- Report rescued exceptions to Canvas::Errors, not just the logger
- Add a spec covering permissions computation with empty/partial career data
When it happens
Trigger: Computing permissions for a Canvas Career (K5/Career Learning) context where the override-apply block raises — e.g. a career account/course object missing expected attributes, a bad permission definition shape, or a database error while loading career role/override records.
Common situations: Environments where the Canvas Career feature flag is on but career data is partially migrated or inconsistent; plugins/gems defining career permissions with unexpected structures; exceptions inside custom career permission override hooks.
Related errors
- Canvas Career permission group overrides failed: #
- ActiveRecord::RecordNotFound
- Cannot change locked status on granular permission
- Cannot import to other courses
- Cannot modify outcome from another context
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/e1990e7d82b857a4.
Report an issue: GitHub.
Appendix: source
Thrown at lib/permissions.rb:87
begin
label_overrides = CanvasCareer::LabelOverrides.permission_label_overrides(context)
if label_overrides.any?
permissions_with_overrides = @permissions.transform_values do |permission_def|
permission_key = @permissions.key(permission_def)
override = label_overrides[permission_key] || {}
if override.any?
new_permission_def = permission_def.dup
new_permission_def = new_permission_def.merge(label: override[:label]) if override[:label]
new_permission_def
else
permission_def
end
end
return permissions_with_overrides
end
rescue => e
Rails.logger.warn("Canvas Career permission overrides failed: #{e.message}")
end
end
@permissions
end
def self.non_masquerading_permissions
return [] unless @permissions.frozen?
@non_masquerading_permissions ||= Set.new(@permissions.keys.select { |perm| @permissions.dig(perm, :not_for_masquerading) })
end
def self.not_for_masquerading?(permission)
if permission.is_a?(Array)
non_masquerading_permissions.intersect?(permission)
else
non_masquerading_permissions.include?(permission)
endView on GitHub (pinned to 1c9f0bb801)