instructure/canvas-lms · error · ImportError

A # did not pass validation (# : # , error: # )

Error message

A #{type_display_name(item_type)} did not pass validation (#{item_type}: #{item.sis_source_id}, error: #{item.errors.full_messages.join(",")})

What it means

Raised in save_and_process_memberships when the Group or GroupCategory record fails ActiveRecord validations on save. CSV-level checks passed, but the resulting model is invalid; the model's error messages are joined into the raised message.

Solutions

  1. Read the embedded error list in the message and fix the offending field.
  2. Truncate names to fit length validations.
  3. Resolve uniqueness conflicts before import.
  4. Build the item locally and call valid? to identify failing validations.

Example fix

# before: 300-char name -> "Name is too long"
item.name = long_name
item.save
# after
item.name = long_name[0, 255]
item.save
Defensive patterns

Strategy: validation

Validate before calling

name = name.to_s
raise ArgumentError, 'name too long (max 255)' if name.length > 255
raise ArgumentError, 'name blank' if name.strip.empty?

Try / catch

begin
  importer.add_group(gid, cat_id, acct_id, course_id, name, status)
rescue ImportError => e
  logger.warn("Model validation failed: #{e.message}")
end

Prevention

When it happens

Trigger: add_group/add_tag rows whose values violate model validations at save time — e.g. name exceeding length limits or uniqueness constraints within a category.

Common situations: Names longer than the DB/validator limit; duplicate names within a category; oversized fields from data migrations; new validations added by upgrades that legacy CSVs violate.

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


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

Appendix: source

Thrown at lib/sis/group_importer.rb:130

          data = SisBatchRollBackData.build_data(sis_batch: @batch, context: item)
          @roll_back_data << data if data

          if status == "deleted"
            gms = SisBatchRollBackData.build_dependent_data(
              sis_batch: @batch,
              contexts: item.group_memberships,
              updated_state: "deleted"
            )
            @roll_back_data.push(*gms) if gms
          end

          @success_count += 1
          true
        else
          msg = "A #{type_display_name(item_type)} did not pass validation "
          msg += "(" + "#{item_type}: #{item.sis_source_id}, error: "
          msg += item.errors.full_messages.join(",") + ")"
          raise ImportError, msg
        end
      end

      def can_change_context?(item, new_context, item_type, item_id)
        if item_type == "differentiation_tag"
          raise ImportError, "Differentiation Tags are not enabled for Account #{context.account.id}." unless new_context.account.allow_assign_to_differentiation_tags?
        end

        return true unless item&.group_memberships&.exists?

        same_context = new_context.id == item.context_id &&
                       new_context.class.base_class.name == item.context_type

        # For groups, we only block moves between courses, but allow other context changes
        if !same_context &&
           ((item.context.is_a?(Course) || new_context.is_a?(Course)) || item_type == "differentiation_tag")
          raise ImportError, "Cannot move #{type_display_name(item_type)} #{item_id} because it has #{item_type}_memberships."
        end

View on GitHub (pinned to 1c9f0bb801)