{"record":{"id":"4c72f5a507ed79ac","repo":"instructure/canvas-lms","slug":"standard-grade-status-not-found","errorCode":null,"errorMessage":"standard grade status not found","messagePattern":"standard grade status not found","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/upsert_standard_grade_status.rb","lineNumber":44,"sourceCode":"\n    def resolve(input:)\n      raise GraphQL::ExecutionError, \"custom gradebook statuses feature flag is disabled\" unless Account.site_admin.feature_enabled?(:custom_gradebook_statuses)\n\n      root_account = context[:domain_root_account]\n      standard_grade_status = input[:id] ? root_account.standard_grade_statuses.find_by!(id: input[:id], status_name: input[:name]) : StandardGradeStatus.new(root_account:, status_name: input[:name])\n\n      required_permission = standard_grade_status.new_record? ? :create : :update\n      unless standard_grade_status.grants_right?(current_user, session, required_permission)\n        raise GraphQL::ExecutionError, I18n.t(\"Insufficient permissions\")\n      end\n\n      if standard_grade_status.update(color: input[:color])\n        { standard_grade_status: }\n      else\n        errors_for(standard_grade_status)\n      end\n    rescue ActiveRecord::RecordNotFound\n      raise GraphQL::ExecutionError, \"standard grade status not found\"\n    end\n  end\nend\n","sourceCodeStart":26,"sourceCodeEnd":48,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/upsert_standard_grade_status.rb#L26-L48","documentation":"Raised by UpsertStandardGradeStatus when ActiveRecord::RecordNotFound escapes resolve — specifically when input[:id] is given but root_account.standard_grade_statuses.find_by!(id:..., status_name:...) matches no row. The rescue clause converts it to a GraphQL::ExecutionError.","triggerScenarios":"Providing input :id that does not exist on the domain root account, OR providing an id that exists but whose status_name does not match the name argument (find_by! requires both id and status_name to match), OR the record lives on a different shard.","commonSituations":"Renaming a status client-side then updating by an old name+id pair; id/name mismatch after someone renamed the status; wrong root account (multi-tenant); stale id after the status was deleted.","solutions":["Confirm both the id AND status_name exactly match an existing record (root_account.standard_grade_statuses.find_by(id: x, status_name: n))","If the name changed, pass the current status_name — the lookup requires both to match","Verify you are operating on the correct root account/shard","Create the status without :id if it genuinely does not exist yet"],"exampleFix":"// before\nupdateStandardGradeStatus({ id: \"7\", name: \"masterd\", color: \"#0F0\" }) // typo'd name\n// after\nupdateStandardGradeStatus({ id: \"7\", name: \"mastery\", color: \"#0F0\" }) // exact stored name","handlingStrategy":"validation","validationCode":"const match = standardGradeStatuses.find(s => s.id === inputId && s.name === inputName)\nif (!match) throw new Error('no status matches given id and name')","typeGuard":null,"tryCatchPattern":"try {\n  await client.mutate(UPSERT_STANDARD_GRADE_STATUS, { id, name, color })\n} catch (e) {\n  if (/standard grade status not found/.test(e.message)) {\n    await refetchStatuses() // id/name mismatch or deleted\n  } else throw e\n}","preventionTips":["Always pass the exact stored status_name together with the id","Re-fetch after renames; never send stale name/id pairs","Confirm the record lives on the queried root account/shard"],"tags":["graphql","record-not-found","mutation"],"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"}