instructure/canvas-lms · error · InvalidDataError

Invalid fields for an outcome

Error message

Invalid fields for an outcome: %{invalid}

What it means

import_outcome rejects outcome objects carrying group-only fields: course_id (GROUP_ONLY_FIELDS). If course_id is present with a non-blank value on an object_type 'outcome' row, the import aborts listing the offending keys. Outcome rows always import into the import context; they cannot re-target courses.

Solutions

  1. Remove course_id from outcome objects and import with the intended Course or Account context instead.
  2. Split the file per target course and run one import per course context.
  3. Blank out course_id (nil or '') for outcome rows in shared-schema files — only present? values trigger the error.

Example fix

// before
{ object_type: 'outcome', vendor_guid: 'o1', course_id: 42, ... }
// after
{ object_type: 'outcome', vendor_guid: 'o1', ... } # run import with course context if needed
Defensive patterns

Strategy: validation

Validate before calling

if outcome[:object_type] == 'outcome' && outcome[:course_id].present?
  raise ArgumentError, "outcome rows cannot set course_id"
end

Type guard

def outcome_only_valid?(obj)
  obj.is_a?(Hash) && !%i[course_id].any? { |k| obj[k].present? }
end

Try / catch

begin
  importer.import_object(outcome)
rescue Outcomes::Import::InvalidDataError => e
  Rails.logger.warn("bad outcome row #{outcome[:vendor_guid]}: #{e.message}")
end

Prevention

When it happens

Trigger: Calling import_object with {object_type: 'outcome', course_id: 42, ...}; reusing an account-level group schema (which supports course_id) for outcome rows.

Common situations: Single combined CSV where every row includes a course_id column; templated payloads that copy group fields onto outcomes; wanting to import the same outcome into many courses and mistakenly adding course_id per row.

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/360f0b1cdc2f12dc. Report an issue: GitHub.

Appendix: source

Thrown at lib/outcomes/import.rb:146

      model.description = group[:description] || ""
      model.workflow_state = group[:workflow_state].presence || "active"
      model.learning_outcome_group = parent
      model.outcome_import_id = outcome_import_id
      model.save!

      if model.workflow_state == "deleted"
        model.destroy!
      end

      model
    end

    def import_outcome(outcome)
      invalid = outcome.keys.select do |k|
        outcome[k].present? && GROUP_ONLY_FIELDS.include?(k)
      end
      if invalid.present?
        raise InvalidDataError, I18n.t(
          "Invalid fields for an outcome: %{invalid}",
          invalid: invalid.map(&:to_s).inspect
        )
      end

      model = find_prior_outcome(outcome)
      model.context = context if model.new_record?

      unless child_context?(context, of: model.context)
        raise InvalidDataError, I18n.t(
          "Outcome with ID %{guid} already exists in another unrelated course or account (%{name})",
          guid: outcome[:vendor_guid],
          name: model.context.name
        )
      end

      allow_indirect = outcome.key?(:course_id)
      parents = find_parents(outcome, context, allow_indirect:)

View on GitHub (pinned to 1c9f0bb801)