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

Must specify an id or an assignment_id and user_id or an…

Error message

Must specify an id or an assignment_id and user_id or an assignment_id and an anonymous_id

What it means

The `submission` resolver supports three lookup shapes: by `id`, by (`assignment_id` + `user_id`), or by (`assignment_id` + `anonymous_id`). Any combination that matches none of these shapes raises this GraphQL::ExecutionError.

Solutions

  1. Use id alone, or ensure assignment_id is paired with user_id, or assignment_id paired with anonymous_id.
  2. For anonymous submissions, fetch the anonymous_id (e.g. from submissions connection) and pass assignment_id + anonymous_id.
  3. Log the full argument set sent to identify which required pair is incomplete.

Example fix

// before
query { submission(assignmentId: "9", userId: "42") { score } }
// anonymous course: userId unknown
// after
query { submission(assignmentId: "9", anonymousId: "anon-8f3") { score } }
Defensive patterns

Strategy: validation

Validate before calling

function validSubmissionArgs(v) {
  if (v.id) return true;
  return Boolean(v.assignment_id) && Boolean(v.user_id || v.anonymous_id);
}
if (!validSubmissionArgs(vars)) throw new Error('submission needs id, or assignment_id+user_id, or assignment_id+anonymous_id');

Type guard

const canLoadSubmission = (v) => Boolean(v.id) || (Boolean(v.assignment_id) && Boolean(v.user_id ?? v.anonymous_id));

Try / catch

try { await gql(SUBMISSION_QUERY, vars); } catch (e) { if (e.message.startsWith('Must specify an id or an assignment_id')) { // complete the pair, e.g. resolve anonymousId then retry } else throw e; }

Prevention

When it happens

Trigger: Calling submission with: no arguments; only id + assignment_id; only assignment_id; assignment_id with neither user_id nor anonymous_id; or all of id/assignment_id/user_id (id takes precedence only when the pair shapes are otherwise complete — any non-matching shape errors).

Common situations: Anonymized courses where user_id is unavailable and the client forgets to supply anonymous_id; partial variable payloads after a refactor; passing user_id but forgetting assignment_id.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at app/graphql/types/query_type.rb:160

               "a graphql or legacy user id",
               required: false,
               prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("User")

      argument :anonymous_id,
               ID,
               "an anonymous id in use when grading anonymously",
               required: false
    end

    def submission(id: nil, assignment_id: nil, user_id: nil, anonymous_id: nil)
      if id && !assignment_id && !user_id && !anonymous_id
        GraphQLNodeLoader.load("Submission", id, context)
      elsif !id && assignment_id && user_id
        GraphQLNodeLoader.load("SubmissionByAssignmentAndUser", { assignment_id:, user_id: }, context)
      elsif !id && assignment_id && anonymous_id
        GraphQLNodeLoader.load("SubmissionByAssignmentAndAnonymousId", { assignment_id:, anonymous_id: }, context)
      else
        raise GraphQL::ExecutionError, "Must specify an id or an assignment_id and user_id or an assignment_id and an anonymous_id"
      end
    end

    field :term, Types::TermType, null: true do
      argument :id,
               ID,
               "a graphql or legacy id",
               required: false,
               prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("Term")
      argument :sis_id, String, "an id from the original SIS system", required: false
    end
    def term(id: nil, sis_id: nil)
      raise GraphQL::ExecutionError, "Must specify exactly one of id or sisId" if (id && sis_id) || !(id || sis_id)
      return GraphQLNodeLoader.load("Term", id, context) if id

      GraphQLNodeLoader.load("TermBySis", sis_id, context) if sis_id
    end

View on GitHub (pinned to 1c9f0bb801)