D4Vinci/Scrapling · error · RuntimeError
Request failed
Error message
Request failed
What it means
A defensive trailing raise at the end of the retry loop in StealthySession.fetch(). In normal flow the loop either returns a Response or re-raises the last exception on the final attempt (the code path even carries `# pragma: no cover`), so this line only fires if the retry loop exits without returning or raising — effectively unreachable except through control-flow anomalies.
Source
Thrown at scrapling/engines/_browsers/_stealth.py:300
return response
except Exception as e:
page_info.mark_error()
if attempt < self._config.retries - 1:
if is_proxy_error(e):
log.warning(
f"Proxy '{proxy}' failed (attempt {attempt + 1}) | Retrying in {self._config.retry_delay}s..."
)
else:
log.warning(
f"Attempt {attempt + 1} failed: {e}. Retrying in {self._config.retry_delay}s..."
)
time_sleep(self._config.retry_delay)
else:
log.error(f"Failed after {self._config.retries} attempts: {e}")
raise
raise RuntimeError("Request failed") # pragma: no cover
class AsyncStealthySession(AsyncSession, StealthySessionMixin):
"""An async Stealthy Browser session manager with page pooling."""
__slots__ = (
"_config",
"_context_options",
"_browser_options",
"_user_data_dir",
"_headers_keys",
)
def __init__(self, **kwargs: Unpack[StealthSession]):
"""A Browser session manager with page pooling, it's using a persistent browser Context by default with a temporary user profile directory.
:param headless: Run the browser in headless/hidden (default), or headful/visible mode.
:param disable_resources: Drop requests for unnecessary resources for a speed boost.View on GitHub (pinned to 5d213a2d47)
Solutions
- Inspect the traceback and the scrapling version; report it upstream since the real failure exception was swallowed
- Update/patch scrapling to a release where the retry loop's control flow is correct
Defensive patterns
Strategy: try-catch
Try / catch
try:
resp = session.fetch(url)
except RuntimeError:
log.exception('internal retry-loop failure')
raise Prevention
- Recognize it as an internal/unreachable guard — capture full traceback and report upstream
- Pin a known-good scrapling version to avoid control-flow regressions
When it happens
Trigger: Only reachable if the for-attempt loop body completes every iteration without returning a Response and without raising — which the current code structure prevents (last attempt re-raises). Practically never seen in the wild.
Common situations: Virtually none; if you see this message it indicates an internal control-flow change/bug in scrapling itself rather than a user mistake.
Related errors
- Session has been already started
- Context manager has been closed
- Failed to get response for {url}
- Argument `selector_config` must be a dictionary.
AI-assisted analysis of D4Vinci/Scrapling@5d213a2d47 (2026-08-14).
Data as JSON: /api/errors/57bfdbd10c9d3a87.
Report an issue: GitHub.