instructure/canvas-lms · error · ImportError

Improper status "# " for institutional tag association…

Error message

Improper status "#{status}" for institutional tag association (tag: #{tag_id}, user: #{user_id})

What it means

Guard in SIS::InstitutionalTagAssociationImporter::Work#add_institutional_tag_association: the status value doesn't match the allowed active/deleted patterns, so ImportError is raised for the tag/user association row.

Solutions

  1. Use 'active' or 'deleted' as the status value
  2. Fix the offending CSV rows and re-import
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at lib/sis/institutional_tag_association_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/f1a8d8db116c3f56. Report an issue: GitHub.

Appendix: source

Thrown at lib/sis/institutional_tag_association_importer.rb:53

    class Work
      attr_accessor :success_count, :roll_back_data

      def initialize(batch, root_account, logger, messages)
        @batch = batch
        @root_account = root_account
        @logger = logger
        @messages = messages
        @success_count = 0
        @roll_back_data = []
        @tags_cache = {}
        @association_batch = []
      end

      def add_institutional_tag_association(tag_id, user_id, status, csv: nil, lineno: nil, row_info: nil)
        raise ImportError, "No institutional_tag_id given for an institutional tag association" if tag_id.blank?
        raise ImportError, "No user_id given for institutional tag association with tag #{tag_id}" if user_id.blank?
        raise ImportError, "No status given for institutional tag association (tag: #{tag_id}, user: #{user_id})" if status.blank?
        raise ImportError, "Improper status \"#{status}\" for institutional tag association (tag: #{tag_id}, user: #{user_id})" unless /\A(active|deleted)/i.match?(status)
        return if @batch.skip_deletes? && /deleted/i.match?(status)

        @association_batch << { tag_id:, user_id:, status:, csv:, lineno:, row_info: }
        process_batch if @association_batch.size >= BATCH_SIZE
      end

      def any_left_to_process?
        @association_batch.any?
      end

      def process_batch
        return unless any_left_to_process?

        batch = @association_batch.shift(BATCH_SIZE)

        user_ids = batch.map { |r| r[:user_id] }.uniq # rubocop:disable Rails/Pluck
        pseudos_by_sis_id = @root_account.pseudonyms.where(sis_user_id: user_ids).preload(:user).index_by(&:sis_user_id)

View on GitHub (pinned to 1c9f0bb801)