Back to Blog
Guide February 26, 2026

How to record a bug reproduction video for GitHub issues

Describe the bug as a step sequence, record a narrated video, attach it to the GitHub issue. Reproducible in 2 minutes, no screen recorder needed.

How to Record a Bug Reproduction Video for GitHub Issues

"Works on my machine" is a support ticket killer. A bug report with a narrated reproduction video — showing exactly what steps trigger the issue, what environment, what the user sees — cuts the back-and-forth from five messages to one.

The problem: recording a clean reproduction video with a screen recorder takes longer than the bug itself. Here's a faster way.

Define the reproduction steps

Write the steps that trigger the bug. Same format you'd put in the issue body — but as a step sequence that gets executed and recorded.

import fs from 'fs';

const res = await fetch('https://api.pagebolt.dev/v1/video', {
  method: 'POST',
  headers: {
    'x-api-key': process.env.PAGEBOLT_API_KEY,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    steps: [
      { action: 'navigate', url: 'https://yourapp.com/dashboard', note: 'Start on the dashboard' },
      { action: 'click', selector: '#settings', note: 'Open settings' },
      { action: 'click', selector: '#billing-tab', note: 'Go to billing tab' },
      { action: 'click', selector: '#update-card', note: 'Click Update Card' },
      { action: 'wait_for', selector: '.error-message', note: 'Error appears' }
    ],
    audioGuide: {
      enabled: true,
      voice: 'nova',
      script: "Reproducing issue #412. {{1}} Navigate to dashboard. {{2}} Open settings. {{3}} Go to billing. {{4}} Click Update Card — {{5}} and the error appears instead of the card form."
    },
    frame: { enabled: true, style: 'macos' },
    pace: 'slow',
    cursor: { style: 'highlight', persist: true }
  })
});

fs.writeFileSync('repro-412.mp4', Buffer.from(await res.arrayBuffer()));

Attach to the GitHub issue

Use the GitHub CLI to create the issue with the video as an attachment:

# Upload video and get URL (via your CDN or GitHub release assets)
gh release upload v0.0.1-repro repro-412.mp4

# Create issue with video link
gh issue create \
  --title "Update Card button shows error instead of card form" \
  --body "$(cat << 'EOF'
## Steps to reproduce

1. Go to Dashboard → Settings → Billing
2. Click **Update Card**
3. Error message appears instead of card form

## Reproduction video

[Watch reproduction video](https://github.com/your-org/your-repo/releases/download/v0.0.1-repro/repro-412.mp4)

## Environment
- Browser: Chrome 121
- Plan: Pro
EOF
)"

As a script for your team

Standardize the format: one JS file per bug, named after the issue number.

// repros/412.js
export const issue = 412;
export const title = "Update Card button shows error instead of card form";
export const steps = [...];
export const narration = "Reproducing issue #412. ...";
// record-repro.js
const issueNum = process.argv[2];
const { steps, narration, issue } = await import(`./repros/${issueNum}.js`);

const res = await fetch('https://api.pagebolt.dev/v1/video', {
  method: 'POST',
  headers: { 'x-api-key': process.env.PAGEBOLT_API_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    steps,
    audioGuide: { enabled: true, script: narration },
    frame: { enabled: true, style: 'macos' },
    pace: 'slow',
    cursor: { style: 'highlight', persist: true }
  })
});

fs.writeFileSync(`repros/repro-${issueNum}.mp4`, Buffer.from(await res.arrayBuffer()));
console.log(`Saved repros/repro-${issueNum}.mp4`);
node record-repro.js 412

Reproducible bug, narrated video, under two minutes. The reproduction steps live in the repo alongside the fix — reviewers can re-run them after the patch to confirm the bug is gone.


Try it free — 100 requests/month, no credit card. → pagebolt.dev

Get Started Free

100 requests/month, no credit card

Screenshots, PDFs, video recording, and browser automation — no headless browser to manage.

Get Your Free API Key →