Troubleshooting

The handful of things that actually go wrong, what each one means, and how to fix it.

The button doesn't show up on my site

Work through these in order:

  • Open the browser console on your page (right-click → Inspect → Console). BugClip explains its own problems there, prefixed with [BugClip]. For example, Missing data-project-key on the script tag means part of the snippet got lost in the paste.
  • Check the snippet is actually on the page. View source and look for it. If your site has a caching layer, it may still be serving the old page.
  • Check the script loads. Open https://bugclip.dev/widget.js in a new tab — you should see JavaScript, not an error page.
  • Check the key. If it's wrong, or the project was deleted, the widget stays hidden on purpose rather than showing a broken button to your visitors. Re-copy the snippet from Widget settings.

“Upload failed” after they captured something

The capture worked and the report was lost at the very last step, which is the most annoying way for this to go wrong.

Nine times out of ten it's a Content Security Policy on your site that doesn't allow connect-src https://bugclip.dev. That setting blocks the upload while letting everything before it work normally, which is why it fails so late. The reporter's browser console will show a CSP violation naming the blocked request.

If there's no CSP involved, it's an ordinary network problem — trying again on a stable connection is usually enough.

“This report is too large to send”

A report can be up to 4 MB in total, and everything shares that budget: the video or screenshot, the optional full-page image, and the voice note.

The size is checked before anything is uploaded, so the review screen stays open with the capture intact. Nothing is lost — the reporter just needs to make it smaller:

  • Trim the recording. Drag the handles in on the timeline to keep just the step that failed. A short clip plus a sentence beats a ten-minute tour anyway.
  • Leave “Also include full page” unticked — it starts that way — or drop the voice note. Either frees room without shortening the recording at all.
  • Use a page recording instead of a screen recording. Screen recordings hit the ceiling fastest: video arrives already compressed, so there's nothing left to squeeze out of it. The default This page recording is an event log — a list of what changed on the page rather than video frames — which gzips down about 10x and so runs much longer. It also stops itself before it grows too big to send.

There's no fixed time limit either way. How long a recording can run depends on how much of the page changes while it's going, so a static form records for far longer than an animated dashboard.

Images are blank boxes in a screenshot

Screenshots are made by rasterizing your page — redrawing it from your own HTML and CSS into a flat image — rather than photographing the screen. That's what makes them instant and permission-free.

The catch is that the browser won't let a page read an image from another domain unless that domain says it's allowed. Permission comes as a header called Access-Control-Allow-Origin (turning it on is usually labelled CORS, for Cross-Origin Resource Sharing). No header, no read — so the image comes through as an empty box.

The widget spots this as it happens, and the report says so. Open it and you'll find an Images that couldn't be captured panel under Technical context, listing the affected URLs grouped by the domain serving them — usually one domain to fix, however many images broke. The same list goes to the reporter's browser console too, prefixed with [BugClip].

The report also puts the real images back. Blocking applies to reading an image into a canvas, never to displaying one, so the report page can load them straight from your own server and lay them over the empty boxes — press Hide missing images on the screenshot to see the capture as it was stored. These previews are fetched live when you open the report, so if an image has changed or been deleted since, you'll see today's version or nothing at all.

The fix belongs to whatever serves those images, not to BugClip. Turn CORS on for that bucket or CDN and the images appear in every capture from then on. S3 and Cloudflare R2 buckets ship with no CORS settings at all, so a custom asset domain is usually the culprit — most public CDNs already send the header.

Only the images are affected. The text, the layout, the note, and the technical context are all captured normally.

Something in a screenshot looks wrong or missing

Rasterizing redraws your page rather than photographing it, so it can only reproduce what it is able to read and re-render. Most pages come through exactly, but a few things can't survive the trip:

  • Embedded frames from another domain — a payment field, a map, a video player, a support chat. Their pixels belong to that domain, so the frame captures as blank.
  • 3D and WebGL canvases whose drawing surface the browser has already discarded. BugClip prevents this on pages where the snippet loads before your app starts, which is another reason to keep it in <head>.
  • Heavy CSS effectsfilter, backdrop-filter, mask-image and 3D transforms. These still render, just without the effect applied.

The widget checks for all of this on every screenshot. Anything it finds is listed in the reporter's console prefixed with [BugClip], and travels with the report so you can see what the image is missing rather than guessing.

When something came through blank, the reporter is also offered a way out: Capture exactly, which asks the browser for permission and then takes the finished pixels straight from the screen. That capture has none of the limits above — it is what they were looking at. It costs one permission prompt, which is why it isn't the default. It's always available from the widget menu as Exact screenshot, and it needs a desktop browser: phones and tablets can't share a screen.

What the reporter is asked varies by browser. Chrome and Edge offer the current tab in a single click. Firefox and Safari show the full picker — a window, or the entire screen — and BugClip can't narrow it for them. Whatever they pick works: they crop the area that matters out of a frozen copy of it. But the attachment checkbox in the editor covers the whole thing they shared, so it names what that is — “the whole screen” rather than “the full page” — and stays unticked unless they choose it.

If your app is built on embeds, maps or 3D and the rasterized shot is usually the wrong one, make exact capture the default for the whole site:

<script
  src="https://bugclip.dev/widget.js"
  data-project-key="pk_..."
  data-capture-mode="exact"
  defer
></script>
Recordings have one of these limits too. A This page recording replays your own DOM, so filters, masks, 3D and WebGL all come back correctly — the replay hands them to a real browser to paint. But it still can't see inside a frame from another domain, so an embedded checkout or video stays empty in the replay. The widget records which frames those were and lists them on the report, and a My screen recording captures them properly.

One more knob, rarely needed: BugClip asks the browser to keep WebGL drawing buffers readable so 3D canvases can be captured at all. That costs a little rendering performance on graphics-heavy pages. To turn it off, add data-webgl-capture="off" to the same script tag — WebGL canvases will then capture as blank boxes, and reporters can still use Exact screenshot for them.

“Nothing happened when I clicked record”

This only affects the My screen option, which needs the browser's permission to record. The reporter dismissed or denied that prompt, and nothing can be captured without it — ask them to try again and allow it.

On a phone or tablet the prompt never appears at all, because mobile browsers can't share the screen. Ask them to use This page instead, which works everywhere.

Reports arrive, but Slack stays quiet

  • Use Send test message in Widget settings first. It tests the webhook on its own, which tells you whether the problem is Slack or BugClip.
  • Slack delivery is a Pro feature. If your trial ended, the webhook is saved but paused — check Billing.
  • If the webhook was deleted or revoked in Slack, generating a new one and saving it fixes things.

A report has no Technical context section

  • The workspace wasn't on Pro when it arrived. Context is discarded on arrival rather than stored, so upgrading now can't fill it in for older reports.
  • The errors happened before the widget loaded. BugClip only sees what happens after it starts, so anything that broke earlier in the page load isn't there.

I can't create a second project

The Free plan includes one project. Unlimited projects come with Pro — see Plans & billing.

Still stuck?

The browser console on the page where the problem happens is the fastest way to find out what BugClip thinks is wrong — everything it reports is prefixed with [BugClip].