instructure/canvas-lms · error · InvalidDataError

The " " field must have no spaces

Error message

The "%{field}" field must have no spaces

What it means

Raised by Outcomes::Import#check_object when the vendor_guid value contains whitespace characters (matched by /\s/). vendor_guid is an external identifier used for lookups and deduplication, so spaces (leading, trailing, or internal) are rejected with an InvalidDataError. The error message names the field as vendor_guid explicitly.

Solutions

  1. Remove all whitespace from the vendor_guid value (use a hyphen or underscore instead of spaces).
  2. Trim and clean the column: gsub(/\s+/, '') or a targeted strip, replacing internal spaces with '_'.
  3. Check for invisible whitespace such as non-breaking spaces before re-importing.

Example fix

// before
vendor_guid: "CCSS ELA-Literacy RST.1"
// after
vendor_guid: "CCSS_ELA-Literacy_RST.1"
Defensive patterns

Strategy: validation

Validate before calling

guid = row['vendor_guid'].to_s
raise "vendor_guid has whitespace" if guid.match?(/\s/)

Try / catch

begin
  importer.run
rescue Outcomes::Import::InvalidDataError => e
  collect_error(e.message) # 'The "vendor_guid" field must have no spaces'
end

Prevention

When it happens

Trigger: vendor_guid like 'ABC 123' with an internal space; cells pasted with trailing whitespace or non-breaking spaces from Excel/Word; IDs copied with a trailing tab.

Common situations: Copy-pasted identifiers containing non-breaking spaces (U+00A0), which \s matches; spreadsheet autoformatting adding spaces; source systems allowing spaces in their external IDs.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at lib/outcomes/import.rb:39

  module Import
    class InvalidDataError < RuntimeError; end

    class DataFormatError < RuntimeError; end

    GROUP_ONLY_FIELDS = %i[course_id].freeze
    OBJECT_ONLY_FIELDS = %i[calculation_method calculation_int ratings].freeze
    VALID_WORKFLOWS = [nil, "", "active", "deleted"].freeze

    def check_object(object)
      %i[vendor_guid title].each do |field|
        next if object[field].present?

        raise InvalidDataError, I18n.t(
          'The "%{field}" field is required', field:
        )
      end
      if object[:vendor_guid].match?(/\s/)
        raise InvalidDataError, I18n.t(
          'The "%{field}" field must have no spaces',
          field: "vendor_guid"
        )
      end
      unless VALID_WORKFLOWS.include? object[:workflow_state]
        raise InvalidDataError, I18n.t(
          '"%{field}" must be either "%{active}" or "%{deleted}"',
          field: "workflow_state",
          active: "active",
          deleted: "deleted"
        )
      end
    end

    def import_object(object)
      check_object(object)

      type = object[:object_type]

View on GitHub (pinned to 1c9f0bb801)