Start with the behavior, not a guess

A reproducible bug report lets someone else observe the same problem without needing to ask what you ran or what you meant. Start with a short title that names the action and result: “Average function raises an error for an empty list” is more useful than “Math is broken.” The report should describe one problem, even if you discovered several while testing.

State what you expected and what actually happened. Keep these separate from your theory about the cause. For example: “Expected: an empty list returns 0, as required by this program. Actual: the program stops with ZeroDivisionError.” That expectation depends on the program’s intended behavior; another program might deliberately reject empty lists. If you are unsure what should happen, say so rather than presenting a preference as a requirement.

Record the setup someone needs to repeat it

Include the program version or commit identifier if one exists, the language runtime version, and the command you used. List dependencies and their versions when they matter. For a small Python script with no external packages, a useful setup might be: “Python 3.11, no third-party packages; run python average.py.” The operating system is worth noting if file paths, permissions, or other system behavior may affect the result. Do not invent a version to make the report look complete; check it or say that it is unknown.

Also describe any starting state the steps depend on. Does a file need to exist? Must a setting be enabled? Is the input typed into a prompt or passed as an argument? If the bug appears only after an earlier action, include that action. Aim for a reader to start from the same conditions rather than trying to reconstruct them from an error message.

Give exact steps and a minimal example

Write the reproduction steps in order, using concrete inputs and commands. For a script, that could be: save the example below as average.py, then run python average.py. The example is short enough to include in the report: def average(values): return sum(values) / len(values); print(average([])). In an actual report, preserve the line breaks and indentation required by Python, with the print call outside the function. Running it calls average with an empty list, so len(values) is zero and the division raises ZeroDivisionError.

A minimal example removes unrelated code while keeping the failure. Reduce the original program gradually: replace private data with harmless sample input, remove unrelated functions, and rerun after each change. If removing a line makes the problem disappear, that line may be important context. Do not simplify so aggressively that the example no longer fails. When a standalone example is not possible, provide the smallest relevant file or input and explain what else is needed.

Capture the result precisely

Copy the exact error message and the relevant traceback or output rather than writing only “it crashes.” Include the command that produced it, and distinguish output from your explanation. For the example, the key observation is that the call with an empty list reaches a division by zero. A traceback can show which line failed; it does not, by itself, establish what the correct empty-list behavior should be.

If the issue is intermittent, record how often you observed it across the attempts you made, along with any conditions that differed. Avoid claiming that a bug “always” happens unless you have repeated the stated steps and seen that result. Remove passwords, tokens, personal information, and private file contents before sharing logs or examples. Replace sensitive values with safe substitutes, then check that the substitutes still reproduce the problem.

Finish with a quick reproduction check

Before sending the report, follow your own instructions from the stated starting point. Confirm that filenames match, commands can be copied, required tools are named, and the actual result matches what you wrote. If a clean setup does not reproduce the issue, update the report with the missing condition instead of leaving readers to guess.

A compact final report can use these labels: Summary; Setup; Steps to reproduce; Expected result; Actual result; Relevant output. Add a minimal example when it helps. A possible fix can go in a separate note, clearly marked as a suggestion. The report’s main job is not to prove why the bug exists; it is to make the observed behavior easy for someone else to see, understand, and investigate.

Back to category ↗