{"record":{"id":"f45de718819e2ffe","repo":"instructure/canvas-lms","slug":"unable-to-find-outcomecalculationmethod","errorCode":null,"errorMessage":"Unable to find OutcomeCalculationMethod","messagePattern":"Unable to find OutcomeCalculationMethod","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/delete_outcome_calculation_method.rb","lineNumber":37,"sourceCode":"#\n\nclass Mutations::DeleteOutcomeCalculationMethod < Mutations::BaseMutation\n  graphql_name \"DeleteOutcomeCalculationMethod\"\n\n  # input arguments\n  argument :id, ID, required: true\n\n  # the return data if the delete is successful\n  field :outcome_calculation_method_id, ID, null: false\n\n  def self.outcome_calculation_method_id_log_entry(_entry, context)\n    context[:deleted_models][:outcome_calculation_method].context\n  end\n\n  def resolve(input:)\n    record_id = GraphQLHelpers.parse_relay_or_legacy_id(input[:id], \"OutcomeCalculationMethod\")\n    record = OutcomeCalculationMethod.active.find_by(id: record_id)\n    raise GraphQL::ExecutionError, \"Unable to find OutcomeCalculationMethod\" if record.nil?\n    raise GraphQL::ExecutionError, \"insufficient permission\" unless record.context.grants_right? current_user, :manage_proficiency_calculations\n\n    context[:deleted_models][:outcome_calculation_method] = record\n    record.destroy\n    { outcome_calculation_method_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_calculation_method.rb#L19-L45","documentation":"The deleteOutcomeCalculationMethod mutation raises \"Unable to find OutcomeCalculationMethod\" when OutcomeCalculationMethod.active.find_by(id:) returns nil — i.e. no active record exists with the parsed relay/legacy id. The active scope excludes soft-deleted records, so a soft-deleted method also produces this error.","triggerScenarios":"Calling deleteOutcomeCalculationMethod with an id of a nonexistent method, a soft-deleted (workflow_state != active) method, or a mistyped id that parses but matches nothing.","commonSituations":"Stale client caches after another user deleted the calculation method, double-submitted mutations, or test fixtures cleaned up between calls.","solutions":["Query the OutcomeCalculationMethod via GraphQL first to confirm the id exists and is active","Use the correct relay global id or valid legacy numeric id","Recreate or restore the outcome calculation method if it was deleted","Check workflow_state is active in the outcome_calculation_methods table"],"exampleFix":"// before\nrecord = OutcomeCalculationMethod.active.find_by(id: record_id)\nraise GraphQL::ExecutionError, \"Unable to find OutcomeCalculationMethod\" if record.nil?\n// after\nrecord = OutcomeCalculationMethod.find_by(id: record_id)\nif record.nil? || record.workflow_state != \"active\"\n  raise GraphQL::ExecutionError, \"Unable to find OutcomeCalculationMethod\"\nend","handlingStrategy":"validation","validationCode":"const method = await query(outcomeCalculationMethod, { id });\nif (!method || method.workflowState !== \"active\") throw new NotFound(id);","typeGuard":"function isActiveMethod(m) {\n  return m != null && m._id != null && m.workflowState === \"active\";\n}","tryCatchPattern":"try {\n  await client.mutate(DELETE_OUTCOME_CALCULATION_METHOD, { id });\n} catch (e) {\n  if (e.message === \"Unable to find OutcomeCalculationMethod\") {\n    refreshList(); // stale id\n  } else throw e;\n}","preventionTips":["Fetch and validate the global id immediately before deletion","Refresh outcome lists after any mutation","Account for soft-deleted records being invisible to active scope","Use the relay global id, not names or legacy fragments"],"tags":["graphql","not-found","outcome-calculation-method","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"}