Skip to main content

Troubleshooting

Most BugPort issues come down to one of a few root causes: a misconfigured auth provider, a widget pointed at the wrong API base, an origin that isn't on an allowed list, or capture limits in the browser. This guide is grouped by area. For each problem you'll find the symptom you'd actually observe, the likely cause, the fix, and a related doc to go deeper.

๐Ÿ’ก

Read the symptom that matches what you see, not the one that matches what you think is wrong. A "404" and a "403" from the widget have completely different causes โ€” the status code is the fastest clue.

Authentication & sign-inโ€‹

Social login fails or loops back to sign-inโ€‹

Likely cause: The OAuth provider isn't enabled in Supabase, or the Supabase redirect allowlist doesn't include your origin's /auth/callback URL. Supabase rejects the redirect, so the session is never established.

Fix: In Supabase Auth, enable the Google and/or GitHub provider you're using, and add your origin's /auth/callback to the redirect allowlist (do this for every domain โ€” local, staging, production). Then retry the sign-in flow.

Related: Security & Privacy

Signed in but no workspace / stuck on onboardingโ€‹

Likely cause: New accounts go through onboarding to create their first workspace. Until that completes, there's no workspace to scope API calls to.

Fix: Finish onboarding to create a workspace. After that, dashboard requests resolve against that workspace.

Related: Getting started โ€” Create a project

Widget setupโ€‹

Widget submissions rejected with 403 / origin rejectedโ€‹

Likely cause: Widget keys are origin-restricted. The origin the widget is running on isn't in the key's allowed-origins list, so the API refuses the submission.

Fix: Add the exact origin (scheme + host + port) to the widget key's allowed origins in the dashboard. Use a key created for the matching environment (local / staging / production).

Related: NPM widget

Widget requests return 404โ€‹

Likely cause: apiBaseUrl doesn't resolve to a BugPort API base ending in /v1. A base without the version prefix hits a non-existent path.

Fix: Set apiBaseUrl so it ends in /v1 โ€” the default is https://api.bugport.dev/v1. Only override it for local or self-hosted setups, and keep the /v1 suffix.

Related: NPM widget

Widget renders nothingโ€‹

Likely cause: The widget requires React 18+ and a client-side mount. On older React, or when rendered only on the server, the component never mounts.

Fix: Upgrade to React 18 or later and ensure the widget mounts on the client (see the SSR note under React rendering). Confirm projectKey (the bp_pub_โ€ฆ key, also accepted as publicKey) is passed and required props are present.

Related: NPM widget

Browser extension captureโ€‹

Extension installed but capture doesn't startโ€‹

Likely cause: Not signed in, or the extension isn't pinned/opened on the page you're reproducing on. Capture only runs after you sign in and click start.

Fix: Sign in to the extension, pin it, open it on the target page, click start capture, reproduce the issue, annotate, add details, then submit. The report then appears in the dashboard.

Related: Browser extension

Some network detail or replay is missingโ€‹

Likely cause: Advanced capture options (network detail level, session replay) are collapsed by default and may be off.

Fix: Open the extension's advanced settings and raise the network detail level or enable replay before capturing.

Related: Browser extension

Network / response body captureโ€‹

No response bodies appear in a reportโ€‹

Likely cause: Either the extension is out of date, or the responses are opaque, cross-origin, or binary โ€” which the browser cannot expose, so they can't be captured. The widget never captures network bodies at all.

Fix: Update the extension to the latest version. Confirm the requests you expect are same-origin and text-based; opaque/cross-origin/binary responses are a hard browser limitation, not a bug. Use the extension (not the widget) when you need network capture.

Related: Bug reports

Captured headers look strippedโ€‹

Likely cause: This is intentional. Sensitive headers are filtered and redaction is applied during capture, so authorization-style headers won't appear verbatim.

Fix: No action needed โ€” this is the privacy behavior. If you need a value to debug, reproduce it in a way that doesn't rely on a filtered header being stored.

Related: Security & Privacy

API configurationโ€‹

Requests work locally but fail in production (or vice versa)โ€‹

Likely cause: The apiBaseUrl or the credential is environment-mismatched โ€” e.g. a local widget key used against the production API, or a base URL missing /v1.

Fix: Match the credential to the environment and confirm the base URL ends in /v1. Dashboard/app requests use a Supabase session JWT as a Bearer token; widget submissions use the bp_pub_โ€ฆ key; MCP access uses a scoped MCP token. Check GET /v1/health and GET /v1/version to confirm you're reaching the API.

Related: API overview

Dashboard visibilityโ€‹

A submitted bug isn't visible in the dashboardโ€‹

Likely cause: You're viewing the wrong workspace or project scope. The API is always workspace-scoped, so a bug filed into one project won't show in another's view.

Fix: Switch to the workspace and project the report was filed under. Confirm the widget key or extension was pointed at the intended project/environment, since that determines where the bug lands.

Related: Dashboard

A widget report shows no screenshot but looks "empty"โ€‹

Likely cause: Widget reports without a screenshot are expected โ€” they render annotations, page path, and feedback. There is no broken image panel by design.

Fix: No action needed. If you want screenshots, prompt reporters to include the optional screenshot, or use the extension which captures one.

Related: Bug reports

React renderingโ€‹

Next.js / SSR hydration mismatch or blank widgetโ€‹

Likely cause: The widget is a client-side React component (React 18+). Rendering it during server-side rendering causes a hydration mismatch or a component that never mounts.

Fix: Mount the widget client-side only. In Next.js, render it in a client component (or dynamically import it with SSR disabled) so it initializes in the browser.

Related: NPM widget

Allowed originsโ€‹

"Origin not allowed" even after adding the domainโ€‹

Likely cause: The allowed-origins entry doesn't exactly match the request origin. Origins are scheme + host + port, so http vs https, localhost vs 127.0.0.1, or a non-default port will mismatch.

Fix: Add the exact origin the browser sends, including scheme and any non-standard port. Add a separate entry for each environment rather than expecting one to cover all. Rotate the key if it may have leaked.

Related: Security & Privacy

Local developmentโ€‹

Widget can't reach the API during local devโ€‹

Likely cause: apiBaseUrl still points at the hosted API, or the local origin isn't in the widget key's allowed origins.

Fix: Point the widget at your local API base โ€” typically http://localhost:8000/v1 โ€” keeping the /v1 suffix. Use a local environment widget key and add your local origin (e.g. http://localhost:3000) to its allowed origins.

Related: Getting started โ€” Quickstart

๐Ÿ’ฌ

Still stuck? Capture the exact symptom โ€” the HTTP status code, the failing origin, and whether you're using the widget, extension, dashboard, or MCP โ€” then check the Security & Privacy page for how scoping works, and the API overview for auth modes. Most reports resolve once the status code and credential type are pinned down.

Next stepsโ€‹