{"record":{"id":"32ff148e85dfc0f6","repo":"instructure/canvas-lms","slug":"unable-to-find-outcomeproficiency","errorCode":null,"errorMessage":"Unable to find OutcomeProficiency","messagePattern":"Unable to find OutcomeProficiency","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/delete_outcome_proficiency.rb","lineNumber":37,"sourceCode":"#\n\nclass Mutations::DeleteOutcomeProficiency < Mutations::BaseMutation\n  graphql_name \"DeleteOutcomeProficiency\"\n\n  # input arguments\n  argument :id, ID, required: true\n\n  # the return data if the delete is successful\n  field :outcome_proficiency_id, ID, null: false\n\n  def self.outcome_proficiency_id_log_entry(_entry, context)\n    context[:deleted_models][:outcome_proficiency].context\n  end\n\n  def resolve(input:)\n    record_id = GraphQLHelpers.parse_relay_or_legacy_id(input[:id], \"OutcomeProficiency\")\n    record = OutcomeProficiency.active.find_by(id: record_id)\n    raise GraphQL::ExecutionError, \"Unable to find OutcomeProficiency\" if record.nil?\n    raise GraphQL::ExecutionError, \"insufficient permission\" unless record.context.grants_right? current_user, :manage_proficiency_scales\n\n    context[:deleted_models][:outcome_proficiency] = record\n    record.destroy\n    { outcome_proficiency_id: record.id }\n  end\nend\n","sourceCodeStart":19,"sourceCodeEnd":45,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/delete_outcome_proficiency.rb#L19-L45","documentation":"The deleteOutcomeProficiency mutation raises \"Unable to find OutcomeProficiency\" when OutcomeProficiency.active.find_by(id:) returns nil — no active record matches the parsed id, including soft-deleted proficiencies excluded by the active scope.","triggerScenarios":"Calling deleteOutcomeProficiency with a nonexistent id, an already soft-deleted proficiency's id, or a malformed id that parses but matches nothing.","commonSituations":"Stale references after another admin deleted the proficiency scales, double-submitted mutations, or environments (test vs prod) with different data.","solutions":["Verify the id via an OutcomeProficiency GraphQL query before deleting","Confirm the record is active (workflow_state == active) in the DB","Use the correct relay global id for the environment you are hitting","Recreate the outcome proficiency if it was deleted unintentionally"],"exampleFix":"// before\nrecord = OutcomeProficiency.active.find_by(id: record_id)\nraise GraphQL::ExecutionError, \"Unable to find OutcomeProficiency\" if record.nil?\n// after\nrecord = OutcomeProficiency.active.find_by(id: record_id)\nif record.nil?\n  raise GraphQL::ExecutionError, \"Unable to find OutcomeProficiency (id: #{record_id})\"\nend","handlingStrategy":"validation","validationCode":"const prof = await query(outcomeProficiency, { id });\nif (!prof) throw new NotFound(id);","typeGuard":"function hasProficiency(p) {\n  return p?.data?.outcomeProficiency != null;\n}","tryCatchPattern":"try {\n  await client.mutate(DELETE_OUTCOME_PROFICIENCY, { id });\n} catch (e) {\n  if (e.message === \"Unable to find OutcomeProficiency\") {\n    invalidateCache(\"outcomeProficiencies\");\n  } else throw e;\n}","preventionTips":["Validate ids against a fresh query before delete mutations","Expect soft-deleted records to be unreachable via active scope","Avoid caching proficiency ids across sessions","Check environment/test-vs-prod data divergence"],"tags":["graphql","not-found","outcome-proficiency","soft-delete"],"backgroundTag":"entity-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"}