{"record":{"id":"176e81b3e466c664","repo":"instructure/canvas-lms","slug":"not-found-update-gradebook-group-filter","errorCode":null,"errorMessage":"not found","messagePattern":"not found","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/update_gradebook_group_filter.rb","lineNumber":55,"sourceCode":"\n    group_selection = SpeedGrader::StudentGroupSelection.new(current_user:, course:)\n    updated_group_info = group_selection.select_group(student_id:)\n    if updated_group_info[:group] != group_selection.initial_group\n      new_group_id = updated_group_info[:group].present? ? updated_group_info[:group].id.to_s : nil\n      context_settings = current_user.get_preference(:gradebook_settings, course.global_id) || {}\n      context_settings.deep_merge!({\n                                     \"filter_rows_by\" => {\n                                       \"student_group_ids\" => new_group_id.present? ? [new_group_id] : []\n                                     }\n                                   })\n      current_user.set_preference(:gradebook_settings, course.global_id, context_settings)\n    end\n    {\n      group_name: updated_group_info[:group]&.name,\n      reason_for_change: updated_group_info[:reason_for_change],\n    }\n  rescue ActiveRecord::RecordNotFound\n    raise GraphQL::ExecutionError, \"not found\"\n  end\nend\n","sourceCodeStart":37,"sourceCodeEnd":58,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/update_gradebook_group_filter.rb#L37-L58","documentation":"The updateGradebookGroupFilter mutation rescues ActiveRecord::RecordNotFound from its service call and re-raises it as a GraphQL::ExecutionError with message \"not found\". It means the gradebook group filter (or the group the filter points at) referenced in the input could not be loaded by the update logic.","triggerScenarios":"Calling updateGradebookGroupFilter with a filter/group id that does not exist, was deleted, or belongs to another course/account so the scoped lookup inside the update service returns nil.","commonSituations":"Two users in the same course where one deletes a group while another still has it open; stale client state after gradebook customization changes; passing a wrong id type to the Relay id prepare function.","solutions":["Reload the gradebook filter/group list via the API to confirm the id still exists before mutating.","Verify the id belongs to the course/account context the request is made in.","Confirm the user has permission to see the group; scoping to grants can make records invisible.","Handle the GraphQL errors entry in the client and refresh gradebook settings state."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// confirm the filter/group still exists before mutating\nconst filters = await fetchGradebookFilters(courseId)\nif (!filters.groups.some(g => g.id === groupId)) throw new Error('group not found')","typeGuard":null,"tryCatchPattern":"try {\n  await updateGradebookGroupFilter(input)\n} catch (e) {\n  if (e.graphQLErrors?.some(g => g.message === 'not found')) {\n    await refreshGradebookSettings()\n  } else { throw e }\n}","preventionTips":["Re-fetch gradebook group filters before each update.","Treat group deletion by other users as a normal race and refresh on 404.","Validate id encoding matches the mutation's Relay id prepare function."],"tags":["graphql","ruby","activerecord","gradebook"],"backgroundTag":"record-not-found","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"}