instructure/canvas-lms · error · ImportError
Improper status "# " for # # .
Error message
Improper status "#{status}" for #{type_display_name(type)} #{id}. What it means
Raised when the 'status' of a group or differentiation tag row is not one of the accepted SIS statuses: available, closed, completed, or deleted (case-insensitive). The importer enforces this vocabulary so downstream record state transitions are well-defined. The message echoes the invalid status plus the item type and id.
Solutions
- Change the status to one of: available, closed, completed, deleted.
- Map source-system statuses to SIS statuses in your CSV generator.
- Use 'deleted' to deactivate the group.
- Validate the status column against the allowed pattern before upload.
Example fix
# before group_id,course_id,name,status G101,C200,Study Group A,active # after group_id,course_id,name,status G101,C200,Study Group A,available
Defensive patterns
Strategy: validation
Validate before calling
ALLOWED = %w[available closed completed deleted]
unless ALLOWED.any? { |s| status.to_s.downcase.start_with?(s) }
raise ArgumentError, "status must be one of #{ALLOWED.join(', ')}"
end Try / catch
begin
importer.add_group(gid, cat_id, acct_id, course_id, name, status)
rescue ImportError => e
logger.warn("Bad status row: #{e.message}")
end Prevention
- Map foreign status vocabularies to SIS statuses before export
- Whitelist status values in the CSV generator
- Pre-validate against /\A(available|closed|completed|deleted)/i
- Never leave the status column blank
When it happens
Trigger: add_group/add_tag receiving a status like 'active', '', 'unpublished', or a typo such as 'availible' — anything not matching /\A(available|closed|completed|deleted)/i.
Common situations: Migrating CSVs from another LMS with different status names; typo'd statuses; translated status columns; legacy scripts emitting 'active' instead of 'available'.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid account_id given for admin
- Invalid status # for admin
- No name given for # # .
- No name given for user
- No role_id or role given for admin
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/c00e81728ef91410.
Report an issue: GitHub.
Appendix: source
Thrown at lib/sis/group_importer.rb:55
@batch = batch
@root_account = root_account
@logger = logger
@success_count = 0
@roll_back_data = []
@accounts_cache = {}
@courses_cache = {}
end
private
def type_display_name(type)
type.tr("_", " ")
end
def invalid_import_item?(id, name, status, type)
raise ImportError, "No #{(type == "group") ? type : "tag"}_id given for a #{type_display_name(type)}." unless id
raise ImportError, "No name given for #{type_display_name(type)} #{id}." if name.blank?
raise ImportError, "Improper status \"#{status}\" for #{type_display_name(type)} #{id}." unless /\A(available|closed|completed|deleted)/i.match?(status)
return true if @batch.skip_deletes? && status =~ /deleted/i
false
end
def find_context(id, id_type, type, item_id)
context = nil
cache = (id_type == :course_id) ? @courses_cache : @accounts_cache
if id
context = cache[id]
context ||= if id_type == :course_id
@root_account.all_courses.active.find_by(sis_source_id: id)
else
@root_account.all_accounts.active.find_by(sis_source_id: id)
end
unless contextView on GitHub (pinned to 1c9f0bb801)