Skip to content

Conversation

conico974
Copy link
Collaborator

Using fetch (or I/O in general) inside of a use cache in an ISR/SSG route would make it crash with a Cannot perform I/O on behalf of a different request error during revalidation request if the instance is warm.

This is because by default it will use AsyncLocalStorage.snapshot() and it will bind everything to the initial request context. The downsides is that use cache function will have access to the full request ALS context from next (i.e. cookies, headers ...)

Copy link

changeset-bot bot commented May 15, 2025

🦋 Changeset detected

Latest commit: f4a744a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@opennextjs/cloudflare Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

pkg-pr-new bot commented May 15, 2025

Open in StackBlitz

pnpm add https://pkg.pr.new/@opennextjs/cloudflare@666

commit: f4a744a

@vicb
Copy link
Contributor

vicb commented May 15, 2025

Thanks for the PR nico 🙏

I'll review tomorrow.

Do you understand why we "perform I/O on behalf of a different request"?

@conico974
Copy link
Collaborator Author

Do you understand why we "perform I/O on behalf of a different request"?

I think i do, basically a function using use cache will be wrapped in this https://github.com/vercel/next.js/blob/62de494f3c28e3a6e949a434047ea3023121d239/packages/next/src/server/app-render/async-local-storage.ts#L55-L65. This is done only once at import time (so on the first request to the instance), subsequent request will then get bound to this initial AsyncLocalStorage context which is associated with the first request.

It might be possible to fix it at the workerd level so that ALS bind or snapshot is not actually bound to the request context, but this is likely tricky.

* This is necessary because the createSnapshot function is causing I/O issues for
* ISR/SSG revalidation in Cloudflare Workers.
* TODO: Find a better fix for this issue.
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please add more details from the PR discussion:

https://github.com/vercel/next.js/blob/62de494f/packages/next/src/server/app-render/async-local-storage.ts#L55-L65

This is because by default it will use AsyncLocalStorage.snapshot() and it will bind everything to the initial request context. The downsides is that use cache function will have access to the full request ALS context from next (i.e. cookies, headers ...)

Copy link
Contributor

@vicb vicb left a comment

Choose a reason for hiding this comment

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

Thanks for the fix!

@conico974 conico974 merged commit e87d8bb into opennextjs:main May 16, 2025
7 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.

2 participants