# Bug Filing Pro

> File a Bugzilla bug directly via the BMO REST API with full power the prefilled enter_bug.cgi form can't do — create the bug AND upload one or more attachments (logs, patches, testcases, screenshots) AND set bug-/attachment-level flags (needinfo?, review?, sec-approval?, approval-mozilla-*?, tracking flags) in one confirmed operation. Also attaches files to, and sets flags on, existing bugs. Use when the user wants to actually submit a bug (not just open a draft form), attach files while filing, or set flags. For a simple file-it-myself-in-the-browser draft with no attachments, prefer the form-based `bug-filing` skill instead. Requires a Bugzilla API key.

- Skill: `mozilla/bug-filing-pro` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add mozilla/bug-filing-pro`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mozilla/bug-filing-pro/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: mozilla (https://skillmd.com/u/mozilla)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/mozilla/bug-filing-pro

---


# Bug Filing (Pro) Skill

Files and edits Bugzilla bugs through the BMO REST API, so it can do what the
form-based `bug-filing` skill cannot: **submit the bug, attach multiple files,
and set every flag** — in a single confirmed run.

> Dependencies and Bugzilla API-key setup live in [`README.md`](./README.md).
> Point the user there if `bmo-file-bug --check-auth` fails.

## When to use this vs. the form-based `bug-filing` skill

- **This skill (`bug-filing-pro`)** — the user wants the bug *actually filed*,
  needs to **attach files** (logs, patches, reduced testcases, `about:support`,
  screenshots) and/or **set flags**, or wants to attach/flag an **existing** bug.
- **Plain `bug-filing`** — the user just wants a prefilled `enter_bug.cgi` form
  opened to review and submit by hand, with no attachments or flags.

The bug is created under the API-key owner's identity. Because of that, **every
write is gated**: always dry-run + preview, then get explicit confirmation,
*then* file. Never skip the confirmation step.

## Security

The Bugzilla API key grants full write access under the user's identity. It is
resolved inside `shared/bmo_client.py` and **never enters the conversation**.
Never read, echo, or pass the key. To verify it is wired up (prints presence and
source path, never the value):

```
python3 .claude/skills/bug-filing-pro/bmo-file-bug --check-auth
```

## Workflow (filing a new bug)

### Step 0 — Verify the API key (do this first)
Run `python3 .claude/skills/bug-filing-pro/bmo-file-bug --check-auth`. If it
reports a key, continue normally. **If no key is found, don't dead-end** — use
`AskUserQuestion` to offer two paths:
- **Set up an API key** — point the user to [`README.md`](./README.md) for the
  one-time setup, then re-check. This unlocks attachments + flags via the API.
- **File it in the browser myself (no key)** — proceed through Steps 1–3 to draft
  the body, then in Step 6 run `create … --browser-file` (no `--dry-run`). That
  opens the prefilled `enter_bug.cgi` form for the user to submit under their own
  account. The form **cannot** carry attachments or flags, so tell the user those
  must be added manually afterward (or set a key to automate). Skip the
  attachment/flag gathering in Step 4 accordingly.

Catching this up front means the user never reaches a final-step "no key" error.

### Step 1 — Determine product and component
If the change touches a file in the tree, run
`./mach file-info bugzilla-component <file>` on a representative file. Output is
`Product :: Component`; split on `::`. If it returns `UNKNOWN`, pick the closest
sensible component. Otherwise ask the user.

### Step 2 — Choose the bug type
- `defect` — shipping software misbehaving (regression, crash, error).
- `enhancement` — a new feature, or changing how a feature behaves.
- `task` — config/refactor/tooling/tests/docs with no user-facing change.

### Step 3 — Draft the summary and description
- Keep the summary short and specific.
- Wrap code identifiers (functions, vars, files, prefs, flags) in backticks.
- For a test-failure bug, link the test dashboard:
  `https://tests.firefox.dev/test.html?test=<path>`.
- Write the description to a file and pass it with `--description-file` (so real
  newlines and markdown survive shell quoting).

### Step 4 — Gather attachments and flags
(Skip this in browser-file mode — `enter_bug.cgi` can't carry attachments or
flags, and they require an API key.)
- Simple files: one `--attach <path>` each (type and `is_patch` auto-detected).
- For per-attachment summaries/flags/privacy, write an `--attachments-json` file
  (schema below).
- Bug-level flags: `--flag 'name:status[:requestee]'` (e.g.
  `--flag 'needinfo:?:dev@mozilla.com'`).
- Tracking flags are *fields*, not flags: `--field cf_status_firefox142=affected`.
- Security/visibility groups: `--group` accepts either the internal group name
  or its visible Bugzilla label. For example,
  `--group 'Security-Sensitive Media Bug'` resolves to `media-core-security`
  before preview and filing.
- Status whiteboard: `--whiteboard '[text]'` sets it directly when creating the
  bug.

### Step 5 — Dry-run and preview (REQUIRED for API filing)
Run with `--dry-run`. Default `--preview html` opens a local page rendering the
full request (fields, flags, attachments table); use `--preview form` to show
the body in BMO's native enter-bug form (body only — do not submit it).

> **Two browser modes, don't confuse them:** `--preview form` is review-only —
> **do not** submit it (the API does the real filing on confirmation, so
> submitting would create a duplicate). `--browser-file` (Step 0 no-key path) is
> the opposite — there you **do** submit the form yourself and the API is never
> used.

(In browser-file mode there's nothing to dry-run; go straight to Step 6.)

```
python3 .claude/skills/bug-filing-pro/bmo-file-bug create \
    --product Core --component "Audio/Video: Playback" \
    --summary "<summary>" --description-file /tmp/desc.md \
    --type defect --severity S2 --priority P2 \
    --flag 'needinfo:?:dev@mozilla.com' \
    --attach /tmp/crash.log --attach /tmp/fix.patch \
    --dry-run --preview html
```

Show the user the printed payload.

### Step 6 — Confirm, then file
Confirm with `AskUserQuestion`, "Looks good, file the bug" as the first
(recommended) option. Only on approval, re-run the **exact same command without
`--dry-run`** (and without `--preview`). The script creates the bug, uploads each
attachment, sets flags, then prints the bug URL.

If an attachment fails after the bug is created, the script reports which
succeeded and prints the precise `bmo-file-bug attach <id> …` retry command —
relay it; the bug itself is already filed.

**No-key path (from Step 0):** run the same `create` command with `--browser-file`
(and no `--dry-run`). It opens the prefilled form in the browser for the user to
submit themselves and prints which attachments/flags it couldn't include. Nothing
is filed by the script — tell the user to click Submit, then add those
attachments/flags manually on the new bug.

## Other operations

> `attach` and `flags` always require an API key (no browser fallback —
> `enter_bug.cgi` can't upload files or set flags).

**Attach to an existing bug:**
```
python3 .claude/skills/bug-filing-pro/bmo-file-bug attach <bug-id> \
    --attach /tmp/repro.html --dry-run --preview html
```

**Set flags / fields on a bug or attachment:**
```
python3 .claude/skills/bug-filing-pro/bmo-file-bug flags <bug-id> \
    --flag 'needinfo:?:dev@mozilla.com' --whiteboard '[triage note]' \
    --field cf_status_firefox142=fixed \
    --attachment <attId> --attachment-flag 'review:+' --dry-run
```

**List a bug's attachments and their flags:**
```
python3 .claude/skills/bug-filing-pro/bmo-file-bug list <bug-id>
```

## Reference

### Flag syntax
`name:status[:requestee]` — status is one of `?` `+` `-` `X`. Colon-separated so
hyphenated names (`sec-approval`, `approval-mozilla-beta`) are unambiguous.
Examples: `review:?:rev@mozilla.com`, `sec-approval:?`, `approval-mozilla-beta:+`.

### `--attachments-json` schema (array of objects)
```json
[
  {
    "path": "/tmp/fix.patch",
    "summary": "Proposed fix",
    "file_name": "fix.patch",
    "content_type": "text/plain",
    "is_patch": true,
    "is_private": false,
    "comment": "optional comment posted with the attachment",
    "flags": [{"name": "review", "status": "?", "requestee": "rev@mozilla.com"}]
  }
]
```
Only `path` is required; everything else is auto-detected or optional.

## Notes
- A new bug is created under the API-key owner's account — confirm before filing.
- BMO has no atomic "create + attach" call: the script creates the bug, then
  uploads attachments one per request, all within the single confirmed run.

