{"record":{"id":"c4efded778179de0","repo":"instructure/canvas-lms","slug":"invalid-filter-keys-for-course-work-widget-invalid-keys-join","errorCode":null,"errorMessage":"invalid filter keys for course work widget: #{invalid_keys.join(\", \")}","messagePattern":"invalid filter keys for course work widget: #(.+?)","errorType":"validation","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/update_widget_dashboard_config.rb","lineNumber":143,"sourceCode":"\n  def validate_course_work_filters!(filters)\n    if filters.key?(\"selectedCourse\")\n      course_value = filters[\"selectedCourse\"]\n      unless course_value.is_a?(String) && (course_value == \"all\" || course_value.match?(/^course_\\d+$/))\n        raise GraphQL::ExecutionError, \"selectedCourse must be 'all' or 'course_{id}'\"\n      end\n    end\n\n    if filters.key?(\"selectedDateFilter\")\n      date_filter = filters[\"selectedDateFilter\"]\n      unless date_filter.is_a?(String) && VALID_DATE_FILTERS.include?(date_filter)\n        raise GraphQL::ExecutionError, \"selectedDateFilter must be one of: #{VALID_DATE_FILTERS.join(\", \")}\"\n      end\n    end\n\n    invalid_keys = filters.keys - [\"selectedCourse\", \"selectedDateFilter\"]\n    unless invalid_keys.empty?\n      raise GraphQL::ExecutionError, \"invalid filter keys for course work widget: #{invalid_keys.join(\", \")}\"\n    end\n  end\n\n  def validate_generic_filters!(filters)\n    filters.each_value do |value|\n      validate_filter_value!(value)\n    end\n  end\n\n  def validate_filter_value!(value)\n    return if value.nil?\n\n    case value\n    when String, Numeric, TrueClass, FalseClass\n      true\n    when Hash, ActionController::Parameters\n      value.each_value { |v| validate_filter_value!(v) }\n    when Array","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/update_widget_dashboard_config.rb#L125-L161","documentation":"The course work widget filter hash permits exactly two keys: \"selectedCourse\" and \"selectedDateFilter\". validate_course_work_filters! raises this GraphQL::ExecutionError when any additional or unknown key is present in the filters hash.","triggerScenarios":"Sending a course work widget update with filters like {\"selectedCourse\": \"all\", \"selectedDateFilter\": \"missing\", \"showUngraded\": true} or {\"dateFilter\": \"submitted\"}.","commonSituations":"Key renamed on the client (e.g. \"dateFilter\" vs \"selectedDateFilter\"); piggy-backing extra settings into the filters hash; copying filters from another widget type.","solutions":["Remove all keys other than \"selectedCourse\" and \"selectedDateFilter\" from the filters hash","Use the exact key names \"selectedCourse\" and \"selectedDateFilter\"","Extend the whitelist in validate_course_work_filters! only if a new key is intentionally added"],"exampleFix":"// before\nfilters: { \"selectedCourse\": \"all\", \"dateFilter\": \"submitted\" }\n// after\nfilters: { \"selectedCourse\": \"all\", \"selectedDateFilter\": \"submitted\" }","handlingStrategy":"validation","validationCode":"const allowedKeys = [\"selectedCourse\", \"selectedDateFilter\"];\nconst invalid = Object.keys(filters).filter((k) => !allowedKeys.includes(k));\nif (invalid.length) throw new Error(`invalid filter keys for course work widget: ${invalid.join(\", \")}`);","typeGuard":"const isCourseWorkFilterShape = (f) => f && Object.keys(f).every((k) => [\"selectedCourse\",\"selectedDateFilter\"].includes(k));","tryCatchPattern":null,"preventionTips":["Define a CourseWorkFilters type and construct payloads only through it","Check for key renames when refactoring client code","Do not merge other widgets' filter objects into course work config"],"tags":["graphql","validation","unknown-key"],"backgroundTag":"invalid-argument-value","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}