forem/forem · warning · ArgumentError
Please choose a badge to award
Error message
Please choose a badge to award
What it means
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.
Source
Thrown at app/controllers/admin/badge_achievements_controller.rb:30
end
def destroy
@badge_achievement = BadgeAchievement.find(params[:id])
if @badge_achievement.destroy
render json: { message: I18n.t("admin.badge_achievements_controller.deleted") }, status: :ok
else
render json: { error: "Something went wrong." }, status: :unprocessable_entity
end
end
def award
@all_badges = Badge.select(:title, :slug).order(title: :asc)
end
def award_badges
if permitted_params[:badge].blank?
raise ArgumentError,
I18n.t("admin.badge_achievements_controller.award")
end
usernames = permitted_params[:usernames].downcase.split(/\s*,\s*/)
include_default_description = permitted_params[:include_default_description] == "1"
message = permitted_params[:message_markdown].presence ||
I18n.t("admin.badge_achievements_controller.congrats", community: ::Settings::Community.community_name)
BadgeAchievements::BadgeAwardWorker
.perform_async(usernames,
permitted_params[:badge],
message,
include_default_description)
flash[:success] = I18n.t("admin.badge_achievements_controller.rewarded")
redirect_to admin_badge_achievements_path
rescue ArgumentError => e
flash[:danger] = e.message
redirect_to admin_badge_achievements_pathView on GitHub (pinned to f354c376a7)
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
Example fix
# before (admin view)
<%= f.select :badge, @all_badges.map { |b| [b.title, b.slug] } %>
# after
<%= f.select :badge, @all_badges.map { |b| [b.title, b.slug] }, { prompt: 'Select a badge' }, required: true %> Defensive patterns
Strategy: validation
Validate before calling
// Client-side: block the submit instead of eating a server ArgumentError
const badge = form.querySelector('[name="badge"]').value;
if (!badge) {
showToast('Please choose a badge to award');
return; // do not POST
}
form.submit(); Try / catch
begin post :award_badges, params: payload rescue ArgumentError => e flash.now[:error] = e.message # 'Please choose a badge to award' render :award, status: :unprocessable_entity end
Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Please choose a role to add.
- You need super admin status to take this action
- Unable to process #{params[:role]}
- Not Found
- Routing Error
AI-assisted analysis of forem/forem@f354c376a7 (2026-08-21).
Data as JSON: /api/errors/4f3e53912bf93f8a.
Report an issue: GitHub.