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
- Set workflow_state to exactly 'active' or 'deleted' (case-sensitive, no surrounding spaces).
- Omit workflow_state or set it to nil/empty string to default to 'active' (import_group sets it via .presence).
- 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
- Normalize case and trim whitespace on workflow_state before import
- Omit the field entirely when unsure — it defaults to active
- Validate whole files against the expected schema before importing
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
- invalid date type: #
- Invalid
- Validation failed: Notice type unknown, must be one of
- [Accessibility::CategoryBreakdownService] dropping unknown…
- An institutional tag category did not pass validation
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)
elseView on GitHub (pinned to 1c9f0bb801)