instructure/canvas-lms · error · ImportError

Category with id "# " didn't exist for institutional tag #

Error message

Category with id "#{category_id}" didn't exist for institutional tag #{tag_id}

What it means

Guard in SIS::InstitutionalTagImporter::Work#add_institutional_tag: the referenced category (by sis category_id) was not found for the root account, so ImportError is raised — the tag row references a category that doesn't exist.

Solutions

  1. Import the category first (same or earlier batch) before tags referencing it
  2. Verify the category_id spelling matches the category's sis id
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at lib/sis/institutional_tag_importer.rb:53 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/300e3f0d27d0af0d. Report an issue: GitHub.

Appendix: source

Thrown at lib/sis/institutional_tag_importer.rb:53

        @root_account = root_account
        @logger = logger
        @success_count = 0
        @roll_back_data = []
        @categories_cache = {}
      end

      def add_institutional_tag(tag_id, category_id, name, description, status)
        raise ImportError, "No institutional_tag_id given for an institutional tag" if tag_id.blank?
        raise ImportError, "No category_id given for institutional tag #{tag_id}" if category_id.blank?
        raise ImportError, "No name given for institutional tag #{tag_id}" if name.blank?
        raise ImportError, "No description given for institutional tag #{tag_id}" if description.blank?
        raise ImportError, "No status given for institutional tag #{tag_id}" if status.blank?
        raise ImportError, "Improper status \"#{status}\" for institutional tag #{tag_id}" unless /\A(active|deleted)/i.match?(status)
        return if @batch.skip_deletes? && /deleted/i.match?(status)

        category = @categories_cache[category_id]
        category ||= InstitutionalTagCategory.find_by(root_account_id: @root_account.id, sis_source_id: category_id)
        raise ImportError, "Category with id \"#{category_id}\" didn't exist for institutional tag #{tag_id}" unless category

        @categories_cache[category_id] = category

        tag = InstitutionalTag.find_by(root_account_id: @root_account.id, sis_source_id: tag_id)
        tag ||= InstitutionalTag.new(category:,
                                     root_account: @root_account,
                                     sis_source_id: tag_id)

        tag.name = name
        tag.description = description
        tag.sis_batch_id = @batch.id
        tag.workflow_state = /deleted/i.match?(status) ? "deleted" : "active"

        if tag.save
          data = SisBatchRollBackData.build_data(sis_batch: @batch, context: tag)
          @roll_back_data << data if data
          @success_count += 1
          maybe_write_roll_back_data

View on GitHub (pinned to 1c9f0bb801)