D4Vinci/Scrapling · error · RuntimeError
No active crawl to stop
Error message
No active crawl to stop
What it means
Spider.pause() forwards a graceful-pause request to the internal CrawlerEngine, which only exists while a crawl is running. Calling pause() before start()/stream() (or after the crawl finished and _engine was reset to None) raises RuntimeError.
Source
Thrown at scrapling/spiders/spider.py:237
"""Configure sessions for this spider.
Override this method to add custom sessions.
The default implementation creates a FetcherSession session.
The first session added becomes the default for `start_requests()` unless specified otherwise.
:param manager: SessionManager to configure
"""
from scrapling.fetchers import FetcherSession
manager.add("default", FetcherSession())
def pause(self):
"""Request graceful shutdown of the crawling process."""
if self._engine:
self._engine.request_pause()
else:
raise RuntimeError("No active crawl to stop")
def _setup_signal_handler(self) -> None:
"""Set up SIGINT handler for graceful pause."""
def handler(_signum: int, _frame: Any) -> None:
if self._engine:
self._engine.request_pause()
else:
# No engine yet, just raise KeyboardInterrupt
raise KeyboardInterrupt
try:
self._original_sigint_handler = signal.signal(signal.SIGINT, handler)
except ValueError:
self._original_sigint_handler = None
def _restore_signal_handler(self) -> None:
"""Restore original SIGINT handler."""View on GitHub (pinned to 5d213a2d47)
Solutions
- Only call pause() while a crawl is active; guard with the same condition the library uses (check the private engine or track crawl state yourself)
- Catch RuntimeError and surface 'not running' to the user in control interfaces
- Use SIGINT (Ctrl+C) during start() runs — the built-in signal handler already performs the graceful pause
Example fix
// before
spider = MySpider()
spider.pause() # nothing running yet
spider.start()
// after
spider = MySpider()
thread = Thread(target=spider.start); thread.start()
# ... later, once the crawl is running
try:
spider.pause()
except RuntimeError:
print("crawl not active") Defensive patterns
Strategy: try-catch
Validate before calling
def safe_pause(spider) -> bool:
try:
spider.pause()
return True
except RuntimeError:
return False Try / catch
except RuntimeError:
pass # no active crawl; nothing to pause Prevention
- Track crawl lifecycle in the controlling code and only enable pause controls while running
- Rely on the built-in SIGINT handler during start() runs
When it happens
Trigger: Calling spider.pause() before spider.start() or before entering the `async for` over spider.stream(); calling it after the crawl completed; calling it from another thread before the engine was constructed.
Common situations: Wiring pause into a UI/CLI that can be clicked before the crawl starts; pausing in a finally block after the crawl already ended; race between a control thread and crawl startup.
Related errors
- Session '{session_id}' is no longer alive. Open a new sessio
- Browser not initialized for proxy rotation mode
- Session has been already started
- Context manager has been closed
- No active crawl. Use this property inside `async for item in
AI-assisted analysis of D4Vinci/Scrapling@5d213a2d47 (2026-08-14).
Data as JSON: /api/errors/4149303c010d9488.
Report an issue: GitHub.