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
- Use id alone, or ensure assignment_id is paired with user_id, or assignment_id paired with anonymous_id.
- For anonymous submissions, fetch the anonymous_id (e.g. from submissions connection) and pass assignment_id + anonymous_id.
- 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
- In anonymized courses, resolve anonymous_id up front instead of user_id.
- Always send assignment_id together with a student identifier; never alone.
- Use id when you have it — it is the simplest valid shape.
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
- Must specify exactly one of id or name
- Must specify exactly one of id or sisId
- Must specify exactly one of ids or sisIds
- A maximum of 50 assessees can be provided at once
- A maximum of 50 assessors can be provided at once
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)