D4Vinci/Scrapling · error · ValueError
'quality' is only valid when 'image_type' is 'jpeg'.
Error message
'quality' is only valid when 'image_type' is 'jpeg'.
What it means
capture_screenshot accepts a quality parameter (JPEG quality 0-100) but Playwright only supports quality for JPEG output. If quality is passed while image_type is 'png' (the default), the server rejects the combination before touching the browser. This mirrors Playwright's own constraint, raised early for a clear message.
Source
Thrown at scrapling/core/ai.py:345
network_idle: bool = False,
timeout: int | float = 30000,
) -> List[ImageContent | TextContent]:
"""Capture a screenshot of a web page using an existing browser session and return it as an image.
A browser session must be opened first with `open_session` (either `dynamic` or `stealthy`); the session ID is then passed here.
:param url: The URL to navigate to and capture.
:param session_id: ID of an open browser session created with `open_session`.
:param image_type: Image format. Defaults to "png". Use "jpeg" for smaller file sizes.
:param full_page: When True, captures the full scrollable page instead of just the viewport. Defaults to False.
:param quality: Image quality (0-100) for JPEG only. Raises if passed with `image_type="png"`.
:param wait: Time in milliseconds to wait after page load before capturing. Defaults to 0.
:param wait_selector: Optional CSS selector to wait for before capturing.
:param wait_selector_state: State to wait for the selector. Defaults to "attached".
:param network_idle: Wait for the page until there are no network connections for at least 500 ms.
:param timeout: Timeout in milliseconds for page operations. Defaults to 30,000.
"""
if quality is not None and image_type != "jpeg":
raise ValueError("'quality' is only valid when 'image_type' is 'jpeg'.")
entry = self._get_session(session_id, expected_type=None)
screenshot_kwargs: Dict[str, Any] = {"type": image_type, "full_page": full_page}
if quality is not None:
screenshot_kwargs["quality"] = quality
captured: Dict[str, Any] = {}
async def _capture(page: Any) -> None:
try:
captured["bytes"] = await page.screenshot(**screenshot_kwargs)
captured["url"] = page.url
except Exception as exc:
captured["error"] = exc
await entry.session.fetch(
url,View on GitHub (pinned to 5d213a2d47)
Solutions
- Use quality only with image_type='jpeg': screenshot(url, image_type='jpeg', quality=80)
- Or drop quality entirely for png output
Example fix
# before await capture_screenshot(session_id=sid, url=url, image_type='png', quality=80) # after await capture_screenshot(session_id=sid, url=url, image_type='jpeg', quality=80)
Defensive patterns
Strategy: validation
Validate before calling
if quality is not None:
assert image_type == 'jpeg', 'quality requires image_type="jpeg"' Type guard
from typing import Optional
def screenshot_args_ok(image_type: str, quality: Optional[int]) -> bool:
return quality is None or image_type == 'jpeg' Prevention
- Only forward quality when the caller explicitly chose jpeg
- Define tool schemas so quality is only exposed alongside image_type='jpeg'
When it happens
Trigger: Calling screenshot with image_type='png' (explicitly or by default) together with quality=80, or setting quality globally in agent config while switching image_type to png for lossless captures.
Common situations: Copy-pasting a full option set from a JPEG example, or LLM agents filling every optional argument with defaults.
Related errors
- Failed to capture screenshot for {url}
- Credentials dictionary must contain both 'username' and 'pas
- Session '{session_id}' not found. Use list_sessions to see a
- Session '{session_id}' is no longer alive. Open a new sessio
- Session '{session_id}' is a '{entry.session_type}' session,
AI-assisted analysis of D4Vinci/Scrapling@5d213a2d47 (2026-08-14).
Data as JSON: /api/errors/9054cd6b9ec4929a.
Report an issue: GitHub.