instructure/canvas-lms · error · GraphQL::ExecutionError
invalid filter keys for todo list widget: #
Error message
invalid filter keys for todo list widget: #{invalid_keys.join(", ")} What it means
The todo list widget filter hash only allows the key "filter". validate_todo_list_filters! raises this GraphQL::ExecutionError when any other key appears in the hash, keeping persisted widget config strictly whitelisted.
Solutions
- Send only {"filter": "..."} for the todo list widget
- Move any other settings out of the filters hash or extend validate_todo_list_filters! if a new key is required
- Double-check the widget_id matches the intended widget
Example fix
// before
filters: { "filter": "all", "groupBy": "course" }
// after
filters: { "filter": "all" } Defensive patterns
Strategy: validation
Validate before calling
const invalid = Object.keys(filters).filter((k) => k !== "filter");
if (invalid.length) throw new Error(`invalid filter keys for todo list widget: ${invalid.join(", ")}`); Type guard
const isTodoFilterShape = (f) => f && Object.keys(f).every((k) => k === "filter");
Prevention
- Keep todo list settings other than "filter" outside the filters hash
- Type the filters payload strictly (e.g. { filter: TodoFilter })
- Review payloads in network logs when adding new UI options
When it happens
Trigger: Sending a mutation for the todo list widget with filters such as {"filter": "all", "showCompleted": true} or {"status": "open"}.
Common situations: Reusing filter payloads built for other widgets (announcements uses "filter" only too, but course work uses selectedCourse/selectedDateFilter); adding new UI toggles without extending the server whitelist; key typos.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- invalid filter keys for announcements widget: #
- invalid filter keys for course work widget: #
- 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…
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/d77a7e636f9de5f8.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/update_widget_dashboard_config.rb:122
end
invalid_keys = filters.keys - ["filter"]
unless invalid_keys.empty?
raise GraphQL::ExecutionError, "invalid filter keys for announcements widget: #{invalid_keys.join(", ")}"
end
end
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
View on GitHub (pinned to 1c9f0bb801)