Filing good first bugs
What is a good first bug
A bug a newcomer can pick up cold and finish in one short patch. The hallmarks:
Narrow scope - one file or one tiny area. Multiple newcomers can work in parallel without conflict.
Self-contained - the bug body contains everything: what to change, where to find it, how to reproduce / verify, and links to the contribution quickref. The contributor should not need to ask follow-up questions.
Low risk - fix is mechanical or obvious. No design decisions, no API redesign, no cross-module reasoning.
Verifiable - there’s a clear signal the patch is correct (a lint that stops firing, a test that passes, a doc that renders, a warning that disappears).
Linter output is just one source of such tasks. Other good sources:
A small typo or wording fix in code/docs the user spotted
Removing one piece of dead code the user identified
Converting one RST doc page to Markdown (or similar mechanical migration)
Replacing one deprecated API call with its successor in a single file
Adding a missing test for one small behavior
Renaming one symbol consistently within a contained module
If the task touches many files, requires API design, or needs deep domain knowledge - it’s not a good first bug. Push back on the user before filing.
Workflow
Understand the task source. The user will point at something: a file, a lint output, a typo, a paragraph of docs, a deprecated call site. Read enough to confirm the work is genuinely narrow.
Decide on bug shape. Prefer one bug per file / per atomic task. Combine only if the user explicitly asks. Multiple small bugs let newcomers work in parallel and is the established Firefox precedent (e.g. bug 2031381).
Propose to the user before filing. Use
AskUserQuestionto confirm scope and which items to file. Never generate bug URLs without explicit approval - filing bugs is user-visible.Open a prefilled
enter_bug.cgiform per bug. There is no MCP tool to create Bugzilla bugs - the user submits each one from the form. Use the URL builder below, which opens it in their browser.Report one line per bug - its title and where it went (product/component). Never paste the URL into your reply. Terminal linkification gives up past some length, and a prefilled form’s URL clears that threshold: it carries the whole bug body percent-encoded in its query string, which ran to 2413 and 2635 characters for two ordinary good-first-bugs. Past the threshold the reader gets an unclickable wall of
%20. It costs you as well as the reader: those characters stay resident in your context and are re-sent with every later request in the session, which is also why the script no longer prints the URL - having it in front of you is what invites pasting it. Do not respond by writing a terser bug body - a good-first-bug has to be self-sufficient, and that is worth more than a URL a reader was never meant to click. The script already put the form in front of the user.
Choosing product/component
Most Firefox good-first-bugs go to Developer Infrastructure / Lint and Formatting when they come from lint output, since that’s the team that owns the trackers. For other sources, route to the component that owns the affected code:
Docs conversions → the component of the docs (often
Developer Infrastructure / Source Documentation)Code typos / dead-code → the component that owns the file
API call-site updates → the component using the API
Ask the user if you’re unsure - don’t guess.
Tracker bug
Good-first-bugs typically blocks: a tracker bug so the metawork is visible. Known trackers:
clippy warnings →
1361342ruff warnings →
1968295Coverity issues →
1230156clang-based static analysis →
712350other linters → ask the user
For non-lint bugs there may or may not be a tracker. Ask the user; if there isn’t one, omit blocked.
Whiteboard
Set the Bugzilla whiteboard (status_whiteboard) to [lang=LANGUAGE] so newcomers can filter good-first-bugs by language. Use the full language name:
Rust →
[lang=rust]Python →
[lang=python]JavaScript →
[lang=js]C++ →
[lang=c++]HTML / CSS →
[lang=html]/[lang=css]Markdown / docs →
[lang=md]
Pick the language of the file the contributor will actually edit. If a bug spans languages, list both: [lang=rust][lang=python].
Mentor
Always set a mentor (bug_mentors) on the bug, defaulting to the bug filer. Without a mentor the bug won’t show up in some good-first-bug dashboards, and a newcomer’s comments or questions may be lost because nobody is clearly responsible for answering them.
The mentor is a Bugzilla account email, which the URL builder resolves from the filer’s Bugzilla API key when you omit --mentor. Do not infer it from an address you already have: a Bugzilla account frequently uses one of its own (a +bmo alias is common), and a corporate address is not evidence about it. A guessed address puts a stranger on the hook for a newcomer’s questions, and one that is no Bugzilla account at all makes enter_bug.cgi reject the submission.
Pass --mentor when the mentor is someone other than the filer, and when the builder reports that it cannot resolve the address - most contributors have no python-bugzilla config for it to read. In that case ask the filer for it. Substituting an address you happen to have is never the answer.
URL builder
Use the helper script scripts/build_url.py (path relative to this skill file) to open each prefilled enter_bug.cgi form:
./scripts/build_url.py "<title>" "<comment>" --tracker 1361342 --lang rust
It opens the form in the user’s default browser and prints a one-line confirmation. --print-url prints the URL instead, for a headless host - and if you use it, hand the user the URL by writing it to a file rather than into your reply, for the length reason in step 5. Run it with --help for the full list of options (--product, --component, --tracker, --keywords, --lang, --mentor). It can also be imported and its build_url() function called directly, which stays offline and omits the mentor unless you pass one; the command line resolves it (see Mentor).
Example: lint warnings (canonical case)
This is the pattern bug 2031381 established. For each candidate file with 1-3 trivial warnings:
Title:
Fix clippy warnings in <path>Body lists the warnings, links searchfox at the first warning line, gives the
./mach lint -W -l clippy <path>reproducer.Product/Component:
Developer Infrastructure / Lint and FormattingBlocks:
1361342
Avoid these lints in good-first-bugs unless the user explicitly accepts the extra scope:
clippy::too_many_arguments- needs API refactoringclippy::missing_safety_doc- needs writing real Safety docsclippy::type_complexity- needs designing atypealias
Quick grouping of warnings by file:
awk '/^\// { f=$0; next } /warning/ { c[f]++; lines[f]=lines[f] "\n" $0 }
END { for (f in c) if (c[f] <= 3) print c[f]"\t"f lines[f] }' clippy.txt | sort -n
Example: typo fix
Title:
Fix typo "recieve" in <path>Body: quote the offending line(s), point at searchfox, give the corrected wording.
Component: whatever owns
<path>.No tracker unless the user names one.
Example: docs conversion
Title:
Convert <path> from RST to MarkdownBody: link to the existing RST file, explain the target is
.mdwith the same content, point to a recent landed conversion as a reference, give./mach doc --no-serve --no-openas the verification command.Component:
Developer Infrastructure / Source Documentation.
Reminders
One bug per atomic task unless the user opts into a combined bug.
Always set a mentor, and never hand-write the address - let the builder resolve it, or ask the filer. Without a mentor the bug is invisible in some dashboards and a newcomer’s questions go unanswered.
Don’t auto-assign - the template explicitly tells contributors not to ask.
Never paste a prefilled URL into your reply - it is long enough to defeat terminal linkification. Let the script open the form, and don’t trim the bug body to shorten it.
Push back on scope that’s too big, too vague, or requires design decisions - those are not good-first-bugs.
Match the component to the work - don’t dump everything under Lint and Formatting if the bug isn’t a lint bug.
Comment body template
The body must be self-sufficient. Adapt this skeleton:
The last paragraph (about auto-assignment) is canonical - keep it verbatim.