instructure/canvas-lms · error · GraphQL::ExecutionError

Not found

Error message

Not found

What it means

CreateDiscussionTopic#resolve rescues ActiveRecord::RecordNotFound and raises GraphQL::ExecutionError "Not found". Inside resolve, this fires when context/lookup helpers (e.g. find_context or checkpoint-related lookups such as Assignment/SubAssignment records for checkpoint discussions) cannot find referenced records. It flattens all missing-record cases into one message.

Solutions

  1. Confirm the context (course/group) id is valid and the course is not deleted before creating topics.
  2. For checkpoint discussions, verify the parent assignment and sub-assignments still exist.
  3. Use properly formatted Relay global ids or valid legacy numeric ids for context_id.
  4. Re-fetch the course context in the UI if the session is long-lived.

Example fix

// before
createDiscussionTopic({contextId: storedCourseId, ...})

// after
const course = await fetchCourse(storedCourseId)
if (!course || course.workflowState === 'deleted') {
  promptSelectCourse(); return
}
createDiscussionTopic({contextId: course.id, ...})
Defensive patterns

Strategy: validation

Validate before calling

const course = await fetchCourse(contextId)
if (!course || course.workflowState !== 'available') throw new Error('invalid context')

Try / catch

try {
  await createDiscussionTopic(input)
} catch (e) {
  if (/Not found/i.test(e.message)) promptReSelectContext()
  else throw e
}

Prevention

When it happens

Trigger: Creating a discussion topic with a context_id/context_type whose course or group no longer exists; checkpoint discussions referencing an assignment that was deleted; bad relay/legacy id format causing lookup failure during override or checkpoint setup.

Common situations: Course deleted or soft-deleted between UI load and submit; automation scripts using stale course ids; checkpoint feature flows where sub-assignments were removed by another teacher; SIS sync removing the course mid-operation.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — 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/517d0e3092263c05. Report an issue: GitHub.

Appendix: source

Thrown at app/graphql/mutations/create_discussion_topic.rb:181

            dates:,
            replies_required: checkpoint[:replies_required],
            updating_user: current_user
          )
        end
      end
    end

    discussion_topic.saved_by = :assignment if discussion_topic.assignment.present?
    return errors_for(discussion_topic) unless discussion_topic.save!

    if input.key?(:ungraded_discussion_overrides)
      overrides = input[:ungraded_discussion_overrides] || []
      update_ungraded_discussion(discussion_topic, overrides)
    end

    { discussion_topic: }
  rescue Checkpoints::DiscussionCheckpointError => e
    raise GraphQL::ExecutionError, e.message
  rescue ActiveRecord::RecordInvalid
    errors_for(discussion_topic)
  rescue ActiveRecord::RecordNotFound
    raise GraphQL::ExecutionError, "Not found"
  end

  def find_context(input)
    context_id = GraphQLHelpers.parse_relay_or_legacy_id(input[:context_id], "Context")

    if input[:context_type] == "Course"
      Course.find(context_id)
    elsif input[:context_type] == "Group"
      Group.find(context_id)
    else
      nil
    end
  end

View on GitHub (pinned to 1c9f0bb801)