Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

FAQ and troubleshooting

1. Plumb fails with a Content Security Policy (CSP) error

Plumb drives Chrome through the DevTools Protocol (CDP). Some sites set strict CSP headers that block CDP’s injected scripts from executing.

Fix: This is a known limitation of the CDP snapshot approach. Plumb reads the rendered DOM after the page loads, so most CSP policies do not interfere. If you hit a CSP block, check whether the site sets script-src to a nonce-only or hash-only policy that explicitly rejects inline evaluation — CDP uses Runtime.evaluate which some strict policies block.

As a workaround, lint a staging or local build of the same page where you control the CSP headers.

See: Install Chromium, ADR 0002 — Chromium version range.

2. How do I lint a page behind authentication?

Plumb opens a fresh headless browser session with no stored cookies or credentials. Auth-protected pages return a login screen instead of the content you want to lint.

Fix: Plumb does not expose a browser-profile flag — it always opens a fresh session with no stored cookies. Serve the page locally without auth, or lint a local build that does not require credentials.

See: CLI reference.

3. Chromium version not supported

Plumb accepts Chromium major versions 131 through 150 inclusive. If your browser reports a version outside this range, plumb lint exits with UnsupportedChromium.

Fix: Install a Chromium or Chrome build whose major version falls within the range. Use chromium --version or google-chrome --version to check. Pass --executable-path to select a specific binary if you have multiple installs.

See: Install Chromium, ADR 0002 — Chromium version range.

4. Why doesn’t Plumb extract CSS-in-JS runtime styles?

Plumb reads computed styles from the rendered DOM — it does not parse source CSS, evaluate JavaScript, or trace style injection at build time. CSS-in-JS libraries (Styled Components, Emotion, Tailwind runtime) inject styles into the document before render, so Plumb sees their output just like any other computed style.

What Plumb does not do is trace which CSS-in-JS call site produced a given computed value. That would require build-tool integration and framework-specific parsers, which is outside Plumb’s scope. Plumb lints the rendered result, not the source.

See: Introduction.

5. I get false positives on off-screen elements

Plumb snapshots the full DOM at each viewport. Elements positioned off-screen (e.g. a mobile nav drawer translated to left: -9999px) are still part of the layout and can trigger spacing or typography rules even though users never see them at that breakpoint.

Fix: Suppress specific rules for known false positives using per-rule overrides in plumb.toml:

[rules."spacing/scale-conformance"]
enabled = false

Or narrow the scope by adjusting your viewports so off-screen breakpoint elements are not rendered.

See: Configuration — per-rule overrides, Rules overview.

6. How do I tune performance for large pages?

plumb lint snapshots every viewport sequentially by default. Large pages with deep DOM trees take longer to snapshot.

Fix: Reduce the number of viewports in plumb.toml to only those you need. For CI, a single desktop viewport is often enough. If snapshot capture itself is slow, check that the page has finished loading — Plumb waits for the load event before snapshotting, so slow-loading resources delay the run.

See: Configuration — viewports.

7. Violations differ between my machine and CI

Plumb’s output is deterministic: given the same snapshot and config, the engine produces byte-identical results. If you see differences between local and CI runs, the snapshot itself differs — usually because the page content or Chromium version changed between runs.

Fix: Pin the same Chromium major version locally and in CI. Confirm with chromium --version. If the page is dynamic (A/B tests, personalized content), lint a stable staging build instead.

See: ADR 0002 — Chromium version range, Install Chromium.

8. Can I use Plumb with Firefox or Safari?

No. Plumb uses the Chrome DevTools Protocol for DOM snapshotting. Firefox and Safari use different debugging protocols and are not supported. Chromium-based browsers (Chrome, Edge, Brave) work as long as their major version is within the supported range.

See: Install Chromium.

9. How do I suppress a single violation?

Plumb does not support inline suppression comments in HTML. To suppress violations, use per-rule overrides in plumb.toml:

[rules."spacing/scale-conformance"]
enabled = false

This disables the rule entirely. There is currently no per-element suppression mechanism.

See: Configuration — per-rule overrides.

10. The MCP server is not found by my AI agent

The agent cannot connect to plumb mcp — the server does not appear in the tool list.

Fix: Check that the plumb binary is on the PATH that the agent inherits. GUI-launched editors (Cursor, VS Code) often get a minimal PATH that excludes ~/.cargo/bin. Use an absolute path in your MCP config if needed. After updating the config, restart the agent or reload the MCP connection.

See: MCP server, Claude Code setup, Cursor setup, Codex setup.

11. plumb lint exits with code 2 but no violations

Exit code 2 means an infrastructure failure, not a lint result. Common causes: the URL is unreachable, Chromium was not found, the config file is invalid, or the page timed out during load.

Fix: Run with -v (or -vv for trace logging) to see the underlying error. Check that the URL is accessible from the machine running Plumb, that Chromium is installed and in the supported version range, and that plumb.toml parses without errors.

See: CLI — exit codes.

12. How do I integrate Plumb into GitHub Actions CI?

Run plumb lint --format sarif in a workflow step and upload the artifact with github/codeql-action/upload-sarif; the GitHub Code Scanning chapter walks through a complete workflow and the exit-code handling.

See: GitHub Code Scanning, CLI — exit codes.