Skip to content

fix(crawlers): Keep Request mutations across handler runs and retries#2076

Merged
vdusek merged 2 commits into
apify:masterfrom
Mantisus:save-request-mutations
Jul 15, 2026
Merged

fix(crawlers): Keep Request mutations across handler runs and retries#2076
vdusek merged 2 commits into
apify:masterfrom
Mantisus:save-request-mutations

Conversation

@Mantisus

Copy link
Copy Markdown
Collaborator

Description

  • This PR ensures that mutations of user_data and headers in a Request persist across request handler runs and retries. The behavior matches Crawlee for JS.

  • In AdaptivePlaywrightCrawler, both the static and the browser runs affect the final request state.

Issues

Testing

  • The tests have been updated to check that all mutations have been saved.

@Mantisus
Mantisus requested review from Pijukatel and vdusek July 14, 2026 21:26
@Mantisus Mantisus self-assigned this Jul 14, 2026
vdusek

This comment was marked as outdated.

@vdusek vdusek left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment thread tests/unit/crawlers/_basic/test_basic_crawler.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes request state persistence across handler runs and retries by removing the per-handler deep-copied Request and instead executing handlers against the original Request instance. This aligns Python behavior with Crawlee for JS and also ensures AdaptivePlaywrightCrawler sub-crawler runs (browser/static probes) can contribute to the final request state.

Changes:

  • Remove Request deep-copy isolation from RequestHandlerRunResult, so handler mutations (e.g., user_data, headers) affect the real request and persist across retries.
  • Simplify BasicCrawler request execution by dropping the swapped_context restoration mechanism and not post-applying request changes.
  • Update unit tests to assert persistence of request/session mutations across retries and across adaptive sub-crawler runs.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/unit/crawlers/_basic/test_basic_crawler.py Expands coverage to verify Request.user_data and Session mutations persist across retries (handler + error handler).
tests/unit/crawlers/_adaptive_playwright/test_adaptive_playwright_crawler.py Updates expectations to reflect shared-request behavior across adaptive probe runs and verifies final persisted request state.
src/crawlee/crawlers/_basic/_context_utils.py Removes swapped_context helper that existed to restore original request after running handlers on an isolated copy.
src/crawlee/crawlers/_basic/_basic_crawler.py Stops using an isolated request copy in handler execution and removes post-run “apply changes back” logic.
src/crawlee/crawlers/_adaptive_playwright/_adaptive_playwright_crawler.py Ensures sub-crawlers share the same original request while still isolating storage-result tracking per sub-crawler run.
src/crawlee/_types.py Removes request deep-copying and “apply request changes” behavior from RequestHandlerRunResult.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@vdusek vdusek changed the title fix(crawlers): Keep Request mutations across handler and retries fix(crawlers): Keep Request mutations across handler runs and retries Jul 15, 2026
Sub crawler pipeline call is dynamically created based on the `rendering_type`.
New copy-like context is created from passed `context` and `state` and is passed to sub crawler pipeline.
A new context is created from passed `context` and `state` and is passed to sub crawler pipeline. The original
`request` is shared, so its mutations persist. Only `result` and `use_state` are isolated per sub crawler.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not an issue of this PR, but it is pretty hard to have a mental model of what can be mutated and what can not, and under which conditions...

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you suggest? Shall we open an issue and revisit it later? Or just document it somewhere?

@vdusek
vdusek merged commit e971279 into apify:master Jul 15, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

context.request.user_data mutations are silently dropped on retry

5 participants