instructure/canvas-lms · error · InvalidDataError

Target course is not a child of current account ( )

Error message

Target course %{course_id} is not a child of current account (%{name})

What it means

When importing with an Account context and a group targets course_id, the found course must be a child of that account (child_context? check). If the course belongs to a different sub-account tree or root account, the import refuses to write into it, naming both the course id and the current account name. This prevents cross-account imports via account-level context.

Solutions

  1. Run the import with the actual parent account (or ancestor) of the target course.
  2. Remove course_id so the group imports into the current account instead.
  3. Move the course under the expected account, or find the course's current account and re-run there.
  4. Verify child_context? logic expectations by checking course.account_chain includes your context.

Example fix

// before
# context: account id 1 (root), course 99 belongs to sub-account 7
{ object_type: 'group', course_id: 99 }
// after
# run import with account 7 as context, or omit course_id
{ object_type: 'group' }
Defensive patterns

Strategy: validation

Validate before calling

course = Course.find_by(id: group[:course_id])
raise ArgumentError, "course not under account" if course && !(course == account || course.account_chain_ids.include?(account.id))

Try / catch

begin
  importer.import_group(group)
rescue Outcomes::Import::InvalidDataError => e
  Rails.logger.warn("course not child of account: #{e.message}")
end

Prevention

When it happens

Trigger: Account context = root account, but course_id points to a course under an unrelated sub-account not within that account's subtree; or the course belongs to a different root account entirely.

Common situations: Migrating outcomes with the wrong (too high or too narrow) account selected; course ids copied from another institution's Canvas; sub-account reorganization moved a course out of the expected account after the CSV was generated.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at lib/outcomes/import.rb:98

        )
      end

      group_context = context

      if group[:course_id].present?
        raise InvalidDataError, I18n.t("Cannot import to other courses") unless context.is_a?(Account)

        group_context = Course.find_by(id: group[:course_id])

        if group_context.nil?
          raise InvalidDataError, I18n.t(
            "Course with canvas id %{id} not found",
            id: group[:course_id]
          )
        end

        unless child_context?(group_context)
          raise InvalidDataError, I18n.t(
            "Target course %{course_id} is not a child of current account (%{name})",
            course_id: group[:course_id],
            name: context.name
          )
        end
      end

      model = find_prior_group(group, group_context)
      unless model.context == group_context
        raise InvalidDataError, I18n.t(
          "Group with ID %{guid} already exists in another unrelated course or account (%{name})",
          guid: group[:vendor_guid],
          name: model.context.name
        )
      end

      parents = find_parents(group, group_context, model:)
      raise InvalidDataError, I18n.t("An outcome group can only have one parent") if parents.length > 1

View on GitHub (pinned to 1c9f0bb801)