{"record":{"id":"4f3e53912bf93f8a","repo":"forem/forem","slug":"please-choose-a-badge-to-award","errorCode":null,"errorMessage":"Please choose a badge to award","messagePattern":"Please choose a badge to award","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"warning","filePath":"app/controllers/admin/badge_achievements_controller.rb","lineNumber":30,"sourceCode":"    end\n\n    def destroy\n      @badge_achievement = BadgeAchievement.find(params[:id])\n\n      if @badge_achievement.destroy\n        render json: { message: I18n.t(\"admin.badge_achievements_controller.deleted\") }, status: :ok\n      else\n        render json: { error: \"Something went wrong.\" }, status: :unprocessable_entity\n      end\n    end\n\n    def award\n      @all_badges = Badge.select(:title, :slug).order(title: :asc)\n    end\n\n    def award_badges\n      if permitted_params[:badge].blank?\n        raise ArgumentError,\n              I18n.t(\"admin.badge_achievements_controller.award\")\n      end\n\n      usernames = permitted_params[:usernames].downcase.split(/\\s*,\\s*/)\n      include_default_description = permitted_params[:include_default_description] == \"1\"\n      message = permitted_params[:message_markdown].presence ||\n        I18n.t(\"admin.badge_achievements_controller.congrats\", community: ::Settings::Community.community_name)\n      BadgeAchievements::BadgeAwardWorker\n        .perform_async(usernames,\n                       permitted_params[:badge],\n                       message,\n                       include_default_description)\n\n      flash[:success] = I18n.t(\"admin.badge_achievements_controller.rewarded\")\n      redirect_to admin_badge_achievements_path\n    rescue ArgumentError => e\n      flash[:danger] = e.message\n      redirect_to admin_badge_achievements_path","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/forem/forem/blob/f354c376a7c5d1330dc40d66f150be8d1289020d/app/controllers/admin/badge_achievements_controller.rb#L12-L48","documentation":"Raised as ArgumentError by Admin::BadgeAchievementsController#award_badges when params[:badge] is blank — the bulk badge-award form was submitted without selecting a badge. The guard runs before usernames are parsed, so no BadgeAchievements::BadgeAwardWorker job is enqueued and no achievements are created.","triggerScenarios":"POST /admin/badge_achievements/award_badges with the badge field missing or empty: submitting the award form before touching the badge select; a scripted POST omitting the badge key; the select rendering empty because no Badge records exist on the instance.","commonSituations":"Admin types usernames and hits submit with the select untouched; browser autofill clobbers the select; fresh Forem install with zero badges defined; automated tooling built against an older field name.","solutions":["Return to /admin/badge_achievements/award and pick a badge from the select before submitting","Add required: true to the badge select markup so the browser blocks blank submits","If the select is empty, create Badge records first via /admin/badges","For automation, include the badge identifier in the badge field and verify field names against the current form"],"exampleFix":"# before (admin view)\n<%= f.select :badge, @all_badges.map { |b| [b.title, b.slug] } %>\n\n# after\n<%= f.select :badge, @all_badges.map { |b| [b.title, b.slug] }, { prompt: 'Select a badge' }, required: true %>","handlingStrategy":"validation","validationCode":"// Client-side: block the submit instead of eating a server ArgumentError\nconst badge = form.querySelector('[name=\"badge\"]').value;\nif (!badge) {\n  showToast('Please choose a badge to award');\n  return; // do not POST\n}\nform.submit();","typeGuard":null,"tryCatchPattern":"begin\n  post :award_badges, params: payload\nrescue ArgumentError => e\n  flash.now[:error] = e.message # 'Please choose a badge to award'\n  render :award, status: :unprocessable_entity\nend","preventionTips":["Mark the badge select required in the form markup","Prefer rendering 422 with a flash over raising ArgumentError from controllers","Seed at least one Badge before exposing the award screen on new instances","Automated award scripts should assert the badge param is present before POSTing"],"tags":["ruby","rails","admin","badges","form-validation"],"backgroundTag":"missing-required-form-field","analyzedSha":"f354c376a7c5d1330dc40d66f150be8d1289020d","analyzedAt":"2026-08-21T12:43:44.428Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}