instructure/canvas-lms · error · ImportError
An institutional tag category did not pass validation
Error message
An institutional tag category did not pass validation (category: #{sis_id}, error: #{category.errors.full_messages.join(",")}) What it means
Raised by SisImports::InstitutionalTagCategoryImporter#add_institutional_tag_category when the InstitutionalTagCategory record fails ActiveRecord save/validation. Unlike the argument checks, this happens after the fields pass the blank checks — a model-level validation (e.g. name uniqueness, sis_source_id constraints, account presence) rejected the save. The message includes the sis_id and the joined model error messages.
Solutions
- Read the interpolated error text (category.errors.full_messages) — it names the failing validation, e.g. 'Name has already been taken'.
- Deduplicate names/sis_source_ids in the institutional_tag_categories CSV for the root account.
- Verify the pre-existing record is findable (same root_account_id and sis_source_id) so the importer updates it instead of creating a duplicate.
- After code/validations changed, confirm InstitutionalTagCategory satisfies them, then re-run the import.
Example fix
// before (CSV) cat-1,Department Tags,desc,active cat-2,Department Tags,desc,active // after cat-1,Department Tags,desc,active cat-2,Course Tags,desc,active
Defensive patterns
Strategy: try-catch
Validate before calling
# Pre-check uniqueness against the model before import
names = rows.map { |r| r[:name] }
duplicates = names.tally.select { |_, c| c > 1 }.keys
raise ArgumentError, "duplicate category names: #{duplicates.join(',')}" unless duplicates.empty? Try / catch
begin
importer.add_institutional_tag_category(sis_id, name, description, status)
rescue SisImports::ImportError => e
# e.message contains category.errors.full_messages
Rails.logger.error("Validation failed: #{e.message}")
end Prevention
- Deduplicate names and sis_source_ids per root account in the CSV.
- Ensure sis_source_id matches the existing record so find_by updates instead of inserting.
- After upgrading, review any new validations on InstitutionalTagCategory.
- Read errors.full_messages in the raised message to pinpoint the failing attribute.
When it happens
Trigger: Saving a category whose name/root_account/sis_source_id violates a model validation — most commonly a duplicate name or duplicate sis_source_id for the same root_account; missing account association; a validation added by a plugin/patch or version upgrade.
Common situations: Re-importing a CSV where two rows share the same category name under one root account; an old sis_source_id colliding with an existing record not matched by find_by (e.g. different root_account/shard); new validations on InstitutionalTagCategory introduced by an upgrade.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- A course did not pass validation
- A # user did not pass validation (user: # , # : # , error…
- A # did not pass validation (# : # , error: # )
- Improper status "# " for institutional tag category #
- No institutional_tag_id given for an institutional tag
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/eb5e94fd31af11ab.
Report an issue: GitHub.
Appendix: source
Thrown at lib/sis/institutional_tag_category_importer.rb:66
category = InstitutionalTagCategory.find_by(root_account_id: @root_account.id, sis_source_id: sis_id)
category ||= InstitutionalTagCategory.new(account: @root_account,
root_account: @root_account,
sis_source_id: sis_id)
category.name = name
category.description = description
category.sis_batch_id = @batch.id
category.workflow_state = /deleted/i.match?(status) ? "deleted" : "active"
if category.save
data = SisBatchRollBackData.build_data(sis_batch: @batch, context: category)
@roll_back_data << data if data
@success_count += 1
maybe_write_roll_back_data
else
msg = "An institutional tag category did not pass validation " \
"(category: #{sis_id}, error: #{category.errors.full_messages.join(",")})"
raise ImportError, msg
end
end
private
def maybe_write_roll_back_data
return if @roll_back_data.count <= 1000
SisBatchRollBackData.bulk_insert_roll_back_data(@roll_back_data)
@roll_back_data = []
end
end
end
end
View on GitHub (pinned to 1c9f0bb801)