{"record":{"id":"eb5e94fd31af11ab","repo":"instructure/canvas-lms","slug":"an-institutional-tag-category-did-not-pass-validation","errorCode":null,"errorMessage":"An institutional tag category did not pass validation (category: #{sis_id}, error: #{category.errors.full_messages.join(\",\")})","messagePattern":"An institutional tag category did not pass validation \\(category: #(.+?), error: #(.+?)\\)","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"lib/sis/institutional_tag_category_importer.rb","lineNumber":66,"sourceCode":"        category = InstitutionalTagCategory.find_by(root_account_id: @root_account.id, sis_source_id: sis_id)\n        category ||= InstitutionalTagCategory.new(account: @root_account,\n                                                  root_account: @root_account,\n                                                  sis_source_id: sis_id)\n\n        category.name = name\n        category.description = description\n        category.sis_batch_id = @batch.id\n        category.workflow_state = /deleted/i.match?(status) ? \"deleted\" : \"active\"\n\n        if category.save\n          data = SisBatchRollBackData.build_data(sis_batch: @batch, context: category)\n          @roll_back_data << data if data\n          @success_count += 1\n          maybe_write_roll_back_data\n        else\n          msg = \"An institutional tag category did not pass validation \" \\\n                \"(category: #{sis_id}, error: #{category.errors.full_messages.join(\",\")})\"\n          raise ImportError, msg\n        end\n      end\n\n      private\n\n      def maybe_write_roll_back_data\n        return if @roll_back_data.count <= 1000\n\n        SisBatchRollBackData.bulk_insert_roll_back_data(@roll_back_data)\n        @roll_back_data = []\n      end\n    end\n  end\nend\n","sourceCodeStart":48,"sourceCodeEnd":81,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/sis/institutional_tag_category_importer.rb#L48-L81","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (CSV)\ncat-1,Department Tags,desc,active\ncat-2,Department Tags,desc,active\n// after\ncat-1,Department Tags,desc,active\ncat-2,Course Tags,desc,active","handlingStrategy":"try-catch","validationCode":"# Pre-check uniqueness against the model before import\nnames = rows.map { |r| r[:name] }\nduplicates = names.tally.select { |_, c| c > 1 }.keys\nraise ArgumentError, \"duplicate category names: #{duplicates.join(',')}\" unless duplicates.empty?","typeGuard":null,"tryCatchPattern":"begin\n  importer.add_institutional_tag_category(sis_id, name, description, status)\nrescue SisImports::ImportError => e\n  # e.message contains category.errors.full_messages\n  Rails.logger.error(\"Validation failed: #{e.message}\")\nend","preventionTips":["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."],"tags":["sis-import","validation","activerecord","ruby"],"backgroundTag":"schema-validation-failed","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}