instructure/canvas-lms · error · InvalidDataError

" " must be either " " or

Error message

"%{field}" must be either "%{active}" or "%{deleted}"

What it means

Outcomes::Import validates every imported object via check_object, which requires workflow_state (if given) to be one of the VALID_WORKFLOWS: nil, empty string, 'active', or 'deleted'. This error is raised for any other value. It exists because the import assigns workflow_state directly to LearningOutcome/LearningOutcomeGroup models and only understands these two states.

Solutions

  1. Set workflow_state to exactly 'active' or 'deleted' (case-sensitive, no surrounding spaces).
  2. Omit workflow_state or set it to nil/empty string to default to 'active' (import_group sets it via .presence).
  3. Strip and downcase the value before passing it into the import, then reject anything not in %w[active deleted].

Example fix

// before
{ object_type: 'outcome', workflow_state: 'Active' }
// after
{ object_type: 'outcome', workflow_state: 'active' }
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED = %w[active deleted].freeze
ws = object[:workflow_state]
raise ArgumentError, "bad workflow_state" if ws.present? && !ALLOWED.include?(ws.to_s.strip)

Type guard

def valid_workflow_state?(ws)
  ws.blank? || %w[active deleted].include?(ws)
end

Try / catch

begin
  importer.import_object(object)
rescue Outcomes::Import::InvalidDataError => e
  Rails.logger.warn("skipped row: #{e.message}")
end

Prevention

When it happens

Trigger: Calling import_object (or check_object) with object[:workflow_state] set to something like 'Active', 'inactive', 'published', or a localized/translated string; whitespace-only or trailing-space values like 'active ' also fail since VALID_WORKFLOWS only has exact matches.

Common situations: CSV/API payloads authored by hand where someone writes 'Active' (wrong case) or 'archived'; clients reusing account-level workflow states ('available', 'created') that are valid elsewhere in Canvas but not here; whitespace accidentally introduced by spreadsheet exports.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at lib/outcomes/import.rb:45

    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]
      case type
      when "outcome"
        import_outcome(object)
      when "group"
        import_group(object)
      else

View on GitHub (pinned to 1c9f0bb801)