instructure/canvas-lms · error
Resource is not closed
Error message
Resource is not closed
What it means
Accessibility::BulkCloseIssuesService#reopen_issues can only reopen a scan that is currently closed. This guard fires when scan.open? is true — the issues were never bulk-closed — so reopening them is a no-op that would incorrectly reset state. It protects the closed_at lifecycle invariant of the accessibility scan.
Solutions
- Check scan.open? before scheduling reopen and skip/no-op when it is already open
- Track closed_at: only call reopen when scan.closed? (closed_at present)
- Make the caller idempotent: catch this error and treat an already-open scan as success
Example fix
// before service.reopen_issues // after service.reopen_issues unless scan.open?
Defensive patterns
Strategy: try-catch
Validate before calling
service.reopen_issues unless scan.open?
Type guard
scan.respond_to?(:open?) && scan.open? == false
Try / catch
begin
service.reopen_issues
rescue RuntimeError => e
Rails.logger.info('scan already open') if e.message == 'Resource is not closed'
end Prevention
- Treat reopen as conditional on scan.closed?
- Make UI actions hide 'reopen' for open scans
- De-duplicate background reopen jobs
When it happens
Trigger: Calling reopen_issues on a scan that was never closed (open_at/closed_at state indicates open); calling reopen twice — the second call hits the already-reopened scan; UI/API double-submit racing with the first reopen that already succeeded.
Common situations: Users clicking an 'undo close' action after the state has already changed; background jobs re-delivering a reopen request; tests or scripts assuming reopen is idempotent.
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
- [A11Y Scan] Skipped resource #
- [Accessibility::CategoryBreakdownService] dropping unknown…
- Caption cannot be empty.
- csp not explicitly set
- validation_error_filename
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/cfcf7a6f645e30eb.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/accessibility/bulk_close_issues_service.rb:45
def call
if close
close_issues
else
reopen_issues
end
end
private
attr_reader :scan, :user_id, :close
def close_issues
scan.bulk_close_issues!(user_id:)
end
def reopen_issues
raise "Resource is not closed" if scan.open?
# Reset closed status
scan.update!(closed_at: nil)
# Trigger a fresh re-scan
# This will:
# - Delete all rescannable issues (active + closed)
# - Scan the resource for current issues
# - Create new active issues
# - Update issue_count
# - Reset closed_at to nil
Accessibility::ResourceScannerService.call(resource: scan.context)
end
end
View on GitHub (pinned to 1c9f0bb801)