Troubleshooting
CLI errors
Section titled “CLI errors”UNAUTHORIZED / 401
Section titled “UNAUTHORIZED / 401”Your API key or session token was rejected.
- In CI: Check that
PXDIFF_API_KEYis set in your workflow’s environment. Keys start withpxd_and are project-scoped — make sure the key belongs to the project you’re targeting. - Locally: Run
pxdiff whoamito check your auth status. If it fails, runpxdiff loginto re-authenticate. - Wrong project: If you’re authenticated but get 401, you may be hitting a project you don’t have access to. Check
pxdiff project setor yourPXDIFF_PROJECTenvironment variable.
402 Payment Required
Section titled “402 Payment Required”Your organization’s credit balance has reached zero. New captures and diffs are blocked until you deposit more credits.
- Your existing data (screenshots, baselines, diffs, approval history) is still accessible.
- Service resumes instantly after depositing credits — no waiting or support ticket needed.
- To prevent this in CI, set a monthly budget alert in the billing settings.
See Billing & Credits for pricing details.
429 Too Many Requests
Section titled “429 Too Many Requests”You’ve hit a rate limit. The CLI will show which limit was reached and when it resets.
- Most limits are per-minute. Wait and retry.
- If you’re hitting limits consistently, check Rate Limits for the current thresholds.
Timeout errors
Section titled “Timeout errors”If the CLI times out waiting for a capture or diff to complete:
- Large suites: Captures with hundreds of screenshots take longer. The CLI polls for completion — if it times out, the capture is likely still running. Check the review UI for status.
- Network issues: Ensure your CI runner or local machine can reach
pxdiff.com.
Capture failures
Section titled “Capture failures”Fonts look wrong or different
Section titled “Fonts look wrong or different”Font rendering differs between operating systems. macOS uses Core Text, Linux uses FreeType — the same font renders differently at the subpixel level.
Fix: Use --docker to run captures inside a consistent Linux container:
pxdiff run --docker -- npx playwright testpxdiff local --docker -- npx vitest runSee Docker for consistent rendering for details.
Animations cause flaky screenshots
Section titled “Animations cause flaky screenshots”If your components have CSS transitions or animations, they can be in different states when the screenshot is taken.
Fix: Use the delay parameter to wait for animations to settle:
// Playwright pluginawait expect(page).toMatchPxdiff({ delay: 500 });
// Ladle story metaMyStory.meta = { pxdiff: { delay: 500 } };Or disable animations globally in your test setup:
*, *::before, *::after { animation-duration: 0s !important; transition-duration: 0s !important;}Scrollbars appear in screenshots
Section titled “Scrollbars appear in screenshots”Overlay scrollbar styles vary by OS and can appear inconsistently in captures.
Fix: Hide scrollbars with CSS in your test environment:
*::-webkit-scrollbar { display: none; }* { scrollbar-width: none; }Dynamic content (timestamps, avatars, random data)
Section titled “Dynamic content (timestamps, avatars, random data)”Screenshots that include live timestamps, randomly generated content, or third-party avatars will differ on every run.
Fix: Mock dynamic data in your test environment, or use ignoreSelectors to mask specific elements:
// LadleMyStory.meta = { pxdiff: { ignoreSelectors: [".timestamp", ".avatar"] } };Diff issues
Section titled “Diff issues””My diffs are always different”
Section titled “”My diffs are always different””If every diff shows changes even when you haven’t modified the component:
-
Cross-platform rendering: The most common cause. If your baseline was captured on a different OS or architecture than your current run, subpixel differences will produce diffs. Use
--dockerand match architectures between local and CI. See Architecture considerations. -
Non-deterministic content: Timestamps, random data, or third-party resources that change between runs. See Dynamic content above.
-
Font loading: pxdiff waits for network inactivity and
document.fonts.readyautomatically, but if you see fallback fonts in screenshots, check that your font URLs are accessible from the capture environment.
Understanding the diff threshold
Section titled “Understanding the diff threshold”pxdiff uses pixelmatch at threshold 0.063 — the same algorithm and threshold as Chromatic. This correctly handles anti-aliasing without flagging subpixel rendering differences as changes.
You can override the threshold per-diff:
pxdiff diff --threshold 0.1 # More lenientpxdiff diff --threshold 0.01 # More strictA higher threshold ignores more subtle differences. A lower threshold catches finer changes but may produce more false positives.
GitHub integration
Section titled “GitHub integration”Check run never appears on my PR
Section titled “Check run never appears on my PR”If pxdiff run completes but no GitHub check appears on your pull request:
-
GitHub App not installed: Install the pxdiff GitHub App on your repository. Go to your organization settings in the pxdiff review UI and follow the GitHub installation link.
-
Permissions: The GitHub App needs
checks: writeandpull_requests: readpermissions on the repository. If you restricted repository access during installation, make sure the target repo is included. -
Branch/commit mismatch: The CLI auto-detects branch and commit from the CI environment. If detection fails (e.g., in a custom CI provider), the check run can’t be linked to your PR. Set
PXDIFF_BRANCHandPXDIFF_COMMITexplicitly:env:PXDIFF_BRANCH: ${{ github.head_ref }}PXDIFF_COMMIT: ${{ github.event.pull_request.head.sha }} -
No diffs in session: Check runs are only created when at least one diff completes in the session. If captures failed or no snapshots changed, no check is posted.
Check run is stuck in “pending”
Section titled “Check run is stuck in “pending””The session may not have been completed. This happens if:
- The CI job was cancelled or timed out before
pxdiff runcould finish. - The child command crashed and the session completion step was skipped.
Subsequent runs on the same PR will create new check runs. Pending checks from abandoned sessions will not resolve automatically — they’re harmless but can be confusing. Re-push to trigger a new run.
Docker issues
Section titled “Docker issues”See the Docker guide troubleshooting section for Docker-specific issues including memory limits, architecture mismatches, and volume problems.
API error codes
Section titled “API error codes”| Status | Meaning |
|---|---|
400 | Bad request — invalid parameters or malformed input |
401 | Unauthorized — invalid or missing API key / session token |
402 | Payment required — insufficient credits |
403 | Forbidden — valid auth but no access to the requested resource |
404 | Not found — resource doesn’t exist or belongs to another project |
409 | Conflict — resource already exists (e.g., duplicate snapshot name in a capture) |
429 | Rate limited — too many requests, check Retry-After header |
500 | Server error — unexpected failure, retry once before reporting |