instructure/canvas-lms · error · GraphQL::ExecutionError
selectedCourse must be 'all' or 'course_
Error message
selectedCourse must be 'all' or 'course_{id}' What it means
The course work widget accepts a "selectedCourse" filter that must be either the literal string "all" or a string matching /^course_\d+$/ (e.g. "course_42"). validate_course_work_filters! raises this GraphQL::ExecutionError for any other value, including bare numeric IDs or non-string types.
Solutions
- Format the value as "all" or "course_<numeric_id>" (e.g. "course_42")
- Ensure the value is a String, not an integer — stringify ids with "course_#{id}"
- Verify the id portion contains digits only (no non-numeric characters)
Example fix
// before
filters: { "selectedCourse": 42 }
// after
filters: { "selectedCourse": "course_42" } Defensive patterns
Strategy: validation
Validate before calling
if (filters.selectedCourse !== undefined) {
const v = filters.selectedCourse;
if (!(typeof v === "string" && (v === "all" || /^course_\d+$/.test(v)))) {
throw new Error("selectedCourse must be 'all' or 'course_{id}'");
}
} Type guard
const isValidSelectedCourse = (v) => typeof v === "string" && (v === "all" || /^course_\d+$/.test(v));
Prevention
- Always prefix course ids with "course_" at the point of serialization
- Keep the value a string — never pass raw integers
- Unit-test the formatter that builds selectedCourse values
When it happens
Trigger: Sending filters["selectedCourse"] = 42 (integer), "42", "course_abc", "Course_42", "", or null for the course work widget.
Common situations: Front-end passing the raw canvas course id instead of the prefixed "course_{id}" string; dropping the prefix during serialization; type coercion turning the value into an integer.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- A maximum of 50 assessees can be provided at once
- A maximum of 50 assessors can be provided at once
- All ConversationMessages must exist within the same…
- Anonymous assignments must be manually posted
- Assignment overrides are not allowed in the parent…
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/f72e0f341130af3d.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/update_widget_dashboard_config.rb:130
def validate_todo_list_filters!(filters)
if filters.key?("filter")
filter_value = filters["filter"]
unless filter_value.is_a?(String) && VALID_TODO_FILTERS.include?(filter_value)
raise GraphQL::ExecutionError, "filter must be one of: #{VALID_TODO_FILTERS.join(", ")}"
end
end
invalid_keys = filters.keys - ["filter"]
unless invalid_keys.empty?
raise GraphQL::ExecutionError, "invalid filter keys for todo list widget: #{invalid_keys.join(", ")}"
end
end
def validate_course_work_filters!(filters)
if filters.key?("selectedCourse")
course_value = filters["selectedCourse"]
unless course_value.is_a?(String) && (course_value == "all" || course_value.match?(/^course_\d+$/))
raise GraphQL::ExecutionError, "selectedCourse must be 'all' or 'course_{id}'"
end
end
if filters.key?("selectedDateFilter")
date_filter = filters["selectedDateFilter"]
unless date_filter.is_a?(String) && VALID_DATE_FILTERS.include?(date_filter)
raise GraphQL::ExecutionError, "selectedDateFilter must be one of: #{VALID_DATE_FILTERS.join(", ")}"
end
end
invalid_keys = filters.keys - ["selectedCourse", "selectedDateFilter"]
unless invalid_keys.empty?
raise GraphQL::ExecutionError, "invalid filter keys for course work widget: #{invalid_keys.join(", ")}"
end
end
def validate_generic_filters!(filters)
filters.each_value do |value|View on GitHub (pinned to 1c9f0bb801)