Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
If Chrome DevTools Protocol says Page.captureScreenshot wasn’t found, first check that you connected to a page target and that the running browser’s /json/protocol actually lists the command. Then verify the method’s exact capitalization, the raw JSON request, and whether your client’s generated protocol types match that browser. The method is documented in CDP’s Page domain, but CDP revisions can differ.
What the error means
Page.captureScreenshot is the CDP command for capturing a page screenshot. It belongs to the Page domain, accepts optional capture settings, and returns image data encoded as base64 in the response’s result.data field. If a server or wrapper says the method wasn’t found, it is not recognizing that exact command at the endpoint or session you are using.
That does not by itself prove the browser cannot take screenshots. The common possibilities are that the connection is aimed at a browser-scoped WebSocket rather than a page target, the selected target is not a page, the running browser does not expose that command in its protocol, the client’s generated bindings were made for a different CDP revision, or the raw request was serialized incorrectly. Check those possibilities in that order instead of changing the method name at random.
Free tools Windows power users keep installed
One-click scans. No signup required.
Diagnose the browser, protocol and target
Use the same host and port as the running browser’s remote-debugging endpoint. Replace HOST and PORT below with the actual values. These requests inspect the browser that is running your job, rather than relying on an online protocol definition that may describe a different revision.
#1 Best Overall
1. Identify the browser endpoint
curl -sS http://HOST:PORT/json/version
Record the Browser, Protocol-Version and webSocketDebuggerUrl values in the response. The endpoint exposed in /json/version is browser-scoped: it is useful for browser metadata and browser-level commands, but it is not the endpoint to assume for a command in the Page domain.
2. Check whether this browser lists the command
curl -sS http://HOST:PORT/json/protocol | jq '.domains[] | select(.domain == "Page") | .commands[] | select(.name == "captureScreenshot")'
This uses jq to search the protocol JSON returned by the running browser. If the output contains the command object, the browser’s advertised protocol includes Page.captureScreenshot. If there is no output, confirm that the response came from the intended browser and that it is valid protocol JSON. If the command is genuinely absent, use a Chrome or Chromium build that exposes it, or choose a capability supported by that build; changing capitalization in your client will not add a missing command.
3. Select a page target, not the browser target
curl -sS http://HOST:PORT/json | jq '.[] | select(.type == "page") | {title, url, webSocketDebuggerUrl}'
Choose a target whose type is page, then connect to that target’s own webSocketDebuggerUrl. A page-domain command sent to the browser-scoped endpoint may fail because that endpoint is for browser-scoped commands. If /json returns no page target, there is no page target in that listing to capture; open or create the page through the setup you use for that browser, then inspect the listing again.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Rank #2
4. Compare the client with the running protocol
Call Browser.getVersion and inspect its product, protocolVersion, revision, userAgent and jsVersion fields. Compare the returned protocol and browser revision with the version your client binding or wrapper was generated for. CDP’s tip-of-tree definition changes frequently, and backward compatibility is not guaranteed. A client that compiles successfully can still lack types or method mappings for the browser it connects to.
Send the method exactly as CDP expects
The raw method string is case-sensitive in practice: use Page.captureScreenshot, with an uppercase P for the domain and lowercase c in captureScreenshot. Do not send page.captureScreenshot, Page.captureScreenshot(), or a wrapper-specific alias as the raw CDP method.
Start with the smallest valid request:
{"id":1,"method":"Page.captureScreenshot"}
Or ask for a PNG and capture beyond the viewport:
{"id":2,"method":"Page.captureScreenshot","params":{"format":"png","captureBeyondViewport":true}}
The response is shaped like this, with the image bytes encoded as base64:
Rank #3
{"id":2,"result":{"data":"<base64 image data>"}}
Match the response to the request by its id. When using a raw WebSocket client, read incoming messages until the response with the ID you sent arrives; do not mistake an intervening event for the command result. If the minimal request works but an option-bearing request does not, remove optional parameters and add them back one at a time to identify the problematic field or value.
Capture parameters you can add
The Page command documents these optional fields:
clip: restricts the captured area to a specified clip.format: selects the image format.quality: supplies an image quality setting where applicable.captureBeyondViewport: controls capture beyond the viewport.fromSurface: controls whether capture is from the surface.optimizeForSpeed: requests optimization for speed.
Begin without options when diagnosing method resolution. Once that succeeds, add only the settings your use case needs. A failure with a parameter-bearing request is a different clue from a failure on the bare method: check the parameter names and values against the protocol exposed by that browser.
When to enable the Page domain
Some client wrappers require an explicit Page.enable call as part of session setup, especially when they manage page events. Follow the wrapper’s setup sequence if it requires that step, but keep the screenshot method string exactly Page.captureScreenshot. Do not treat Page.enable as a substitute for using a page-target connection or a compatible protocol binding.
Runnable Python example: discover a page and save its screenshot
This example uses websocket-client to inspect the target list, connect to the first page target, send the raw command, and decode the returned image. Install the dependency with python -m pip install websocket-client. Set CDP_BASE to the browser’s HTTP debugging address, including its port.
import base64
import json
import os
import urllib.request
from websocket import create_connection
CDP_BASE = os.environ.get("CDP_BASE", "http://127.0.0.1:9222")
with urllib.request.urlopen(f"{CDP_BASE}/json/version", timeout=10) as response:
version = json.load(response)
print("Browser:", version.get("Browser"))
print("Protocol-Version:", version.get("Protocol-Version"))
with urllib.request.urlopen(f"{CDP_BASE}/json", timeout=10) as response:
targets = json.load(response)
page = next((target for target in targets if target.get("type") == "page"), None)
if page is None:
raise RuntimeError("No page target found at /json")
ws = create_connection(page["webSocketDebuggerUrl"], timeout=30)
try:
# Some wrappers require Page.enable as session setup; the screenshot
# method itself remains Page.captureScreenshot.
ws.send(json.dumps({"id": 1, "method": "Page.enable"}))
while True:
message = json.loads(ws.recv())
if message.get("id") == 1:
if "error" in message:
raise RuntimeError(f"Page.enable failed: {message['error']}")
break
ws.send(json.dumps({
"id": 2,
"method": "Page.captureScreenshot",
"params": {"format": "png", "captureBeyondViewport": True}
}))
while True:
message = json.loads(ws.recv())
if message.get("id") == 2:
if "error" in message:
raise RuntimeError(f"Screenshot failed: {message['error']}")
image_data = base64.b64decode(message["result"]["data"])
with open("screenshot.png", "wb") as image_file:
image_file.write(image_data)
print("Saved screenshot.png")
break
finally:
ws.close()
If your wrapper does not require Page.enable, the screenshot request can be sent directly after connecting. If this example reports that no page exists, inspect /json and the browser launch/session setup before debugging the screenshot method. If the command is rejected despite selecting a page target, compare the browser’s /json/protocol with the client version and test the minimal request without parameters.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsFixes by symptom
| What you observe | Likely cause | What to do |
|---|---|---|
The raw command is rejected as unknown, and the command is absent from /json/protocol. |
The running browser does not advertise this Page command in its protocol. | Use a Chrome or Chromium build that exposes Page.captureScreenshot, or use a screenshot capability that the current build supports. |
| The protocol lists the command, but a raw call to the browser WebSocket fails. | The connection is browser-scoped rather than attached to a page target. | Choose a target of type page from /json and connect to its webSocketDebuggerUrl. |
| The command works through one client but the wrapper claims it is missing. | The wrapper’s generated types or mappings may be for another CDP revision. | Update the wrapper or regenerate its protocol types for the connected browser revision; verify the raw method string remains unchanged. |
| A request fails only after adding options. | The issue may be a parameter or value rather than method resolution. | Retry the bare method, then add documented options individually and check them against the running browser’s protocol. |
| The request appears to receive no result, or the client reports an unexpected response. | The client may not be correlating messages with request IDs, or may be treating an event as the result. | Send an integer id, then read until a response with that same ID arrives. Inspect the matching response’s result or error field. |
| The screenshot data is received but cannot be written as an image. | The data value is base64 text, not raw PNG bytes. |
Base64-decode result.data before writing the bytes to a file, as in the Python example. |
Keep protocol compatibility and capture behavior predictable
For repeatable automation, record the browser product and protocol version alongside the client version in your deployment notes. Test against the browser build that will run in production, and pin or update browser and client bindings deliberately rather than assuming tip-of-tree documentation matches every installed browser. The live /json/protocol response is the relevant check when a method’s availability is in question.
Best Value
For a first successful capture, use one page target, the bare method or a minimal PNG request, and a fresh request ID. Only then add clipping or other capture settings. This isolates endpoint and compatibility faults from capture configuration. If you maintain a wrapper, ensure its generated command types reflect the browser revision you actually support; the Go CDP binding’s CaptureScreenshot() method is one example of a client abstraction over the command, but a wrapper still needs to communicate with a compatible endpoint.
Or skip the browser setup
If your goal is simply to obtain a website screenshot—not to debug a CDP integration—you can use ScreenshotNeo, a screenshot API and MCP server from Yorker Media. It avoids managing the browser WebSocket and target selection yourself.
One GET request returns an image or PDF; for example, save the response as WebP:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request details. Before capture, it accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be turned off. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies page verdict and billing status in headers. An MCP server provides take_screenshot, get_page_info and capture_pdf tools for AI agents and MCP clients such as Claude and Cursor. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.
FAQ
Will retrying the same request usually fix a “wasn’t found” error?
A retry alone does not resolve a wrong target, unsupported command, mismatched client binding or malformed method. Recheck the endpoint, protocol and request before retrying.
Can I use a newer online CDP reference to decide what my installed browser supports?
Use the running browser’s /json/protocol for that decision. The online tip-of-tree protocol changes frequently and is not guaranteed to be backward-compatible with every browser build.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

