instructure/canvas-lms · error · InvalidDataError

Friendly description is too long (maximum is 255 characters)

Error message

Friendly description is too long (maximum is 255 characters)

What it means

Raised by Outcomes::CsvImporter#import_row when the friendly_description column value exceeds 255 characters. LearningOutcome friendly_description is stored in a varchar(255) column, so the importer pre-validates length and raises InvalidDataError rather than letting the DB fail. The limit is on character length of the plain-text short description.

Solutions

  1. Shorten the friendly_description cell to 255 characters or fewer.
  2. Move the long text into the description column, keeping friendly_description as a concise label.
  3. Pre-validate the column lengths in a script before running the import.

Example fix

// before
friendly_description: "An extremely long description..."*(200 chars more)
// after
friendly_description: description.first(255) # or a concise summary
Defensive patterns

Strategy: validation

Validate before calling

desc = row['friendly_description'].to_s
raise 'friendly_description exceeds 255 chars' if desc.length > 255

Try / catch

begin
  importer.run
rescue Outcomes::Import::InvalidDataError => e
  mark_row_failed(e.message)
end

Prevention

When it happens

Trigger: A row whose friendly_description cell contains more than 255 characters (e.g. a full paragraph pasted into the short description column instead of the long description column).

Common situations: Authors confusing friendly_description (short display name/description) with the full description field; copy-pasting marketing text; migrations from systems without a 255-char cap.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at lib/outcomes/csv_importer.rb:165

      invalid = (headers - OPTIONAL_FIELDS - REQUIRED_FIELDS).map(&:to_s)
      raise ParseError, I18n.t("Invalid fields: %{fields}", fields: invalid.inspect) unless invalid.empty?

      headers
    end

    def import_row(headers, row)
      simple = headers.zip(row).to_h
      ratings = row[headers.length..]

      object = simple.to_h
      object[:ratings] = parse_ratings(ratings)
      object[:learning_outcome_group_id] = @import[:learning_outcome_group_id]
      if object[:mastery_points].present?
        object[:mastery_points] = strict_parse_float(object[:mastery_points], I18n.t("mastery points"))
      end
      if object[:friendly_description].present? && object[:friendly_description].length > 255
        raise InvalidDataError, I18n.t("Friendly description is too long (maximum is 255 characters)")
      end

      import_object(object)
    end

    def parse_ratings(ratings)
      prior = nil
      drop_trailing_nils(ratings).each_slice(2).to_a.map.with_index(1) do |(points, description), index|
        raise InvalidDataError, I18n.t("Points for rating tier %{index} not present", index:) if points.nil? || points.blank?

        points = strict_parse_float(points, I18n.t("rating tier %{index} threshold", index:))

        if prior.present? && prior < points
          raise InvalidDataError, I18n.t(
            "Points for tier %{index} must be less than points for prior tier (%{points} is greater than %{prior})",
            index:,
            prior:,
            points:

View on GitHub (pinned to 1c9f0bb801)