Next.JS Fails to Update Prerender Cache with Time-based Revalidation
Before opening, please confirm:
- [X] I have checked to see if my question is addressed in the FAQ.
- [X] I have searched for duplicate or closed issues.
- [X] I have read the guide for submitting bug reports.
- [X] I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
- [X] I have removed any sensitive information from my code snippets and submission.
App Id
d3v90eh9vhzxl4
AWS Region
us-east-1
Amplify Hosting feature
SSR
Frontend framework
Next.js
Next.js version
13.4.12
Next.js router
App Router
Describe the bug
Next.JS is unable to update the prerender cache as part of the incremental site regeneration process. Since the web compute runtime is unable to write out regenerated pages to the filesystem, Amplify continues to serve up stale pages.
Expected behavior
When specifying a revalidation interval, Amplify web compute regenerates pages based on (re)fetched data and serves the regenerated pages up to visitors based on cache controls.
Reproduction steps
- Create a Next.JS application using the app router
- Enable time-based revalidation (documented here)
- Deploy to Amplify
Build Settings
version: 1
frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
- env | grep -e MY_CREDENTIALS_PREFIX_ >> .env.production
- npm run build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- node_modules/**/*
- .next/cache/**/*
Log output
Failed to update prerender cache for /my-page [Error: EROFS: read-only file system, open '/tmp/app/.next/server/app/my-page.html'] {
errno: -30,
code: 'EROFS',
syscall: 'open',
path: '/tmp/app/.next/server/app/my-page.html'
}
Additional information
No response
Possibly related to https://github.com/aws-amplify/amplify-hosting/issues/3271
Hi @owenfarrell @grundmanise 👋 , thanks for raising this and apologies for the inconvenience caused due to this behavior with the pre-rendering of the cache during the ISR process.
I was able to reproduce this behavior and am currently investigating into it further. I'll keep you posted with any updates.
I had the same issue here. Using NextJS 13.5.4
Any updates on this issue?
any updates? i also have this problem
I found issues dating back to 2022 about planned support for ISR. It is now 2024. Is this still a planned feature?
https://github.com/aws-amplify/amplify-hosting/issues/3116
I have the same log output .
Failed to update prerender cache for /index [Error: EROFS: read-only file system, open '/tmp/app/.next/server/app/index.html']
And it seems this issue occurs only for App Router pages.
I downloaded the build artifact and checked compute/run.sh. It seemas that Amplify Hosting creates the directory .next/server/pages as special.
#!/bin/bash
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset AWS_SESSION_TOKEN
mkdir -p '/tmp/app/.next/server/pages'
echo '[x-amplify-log][INFO] starting copy'
cp -r '/var/task/.next/server/pages' '/tmp/app/.next/server'
echo '[x-amplify-log][INFO] copy server pages complete'
cp -f /var/task/server.js /tmp/app/server.js
echo '[x-amplify-log][INFO] symlink creation complete path=.next'
ln -sf '/var/task/.next/server/app' '/tmp/app/.next/server/app'
# other sym links
node /tmp/app/server.js
Full run.sh
#!/bin/bash unset AWS_ACCESS_KEY_ID unset AWS_SECRET_ACCESS_KEY unset AWS_SESSION_TOKEN mkdir -p '/tmp/app/.next/server/pages' echo '[x-amplify-log][INFO] starting copy' cp -r '/var/task/.next/server/pages' '/tmp/app/.next/server' echo '[x-amplify-log][INFO] copy server pages complete' cp -f /var/task/server.js /tmp/app/server.js echo '[x-amplify-log][INFO] copy complete' ln -sf '/var/task/amplify-compute-bundle-output' '/tmp/app/amplify-compute-bundle-output' ln -sf '/var/task/node_modules' '/tmp/app/node_modules' ln -sf '/var/task/package.json' '/tmp/app/package.json' ln -sf '/var/task/public' '/tmp/app/public' echo '[x-amplify-log][INFO] Root symlink creation complete' ln -sf '/var/task/.next/BUILD_ID' '/tmp/app/.next/BUILD_ID' ln -sf '/var/task/.next/app-build-manifest.json' '/tmp/app/.next/app-build-manifest.json' ln -sf '/var/task/.next/app-path-routes-manifest.json' '/tmp/app/.next/app-path-routes-manifest.json' ln -sf '/var/task/.next/build-manifest.json' '/tmp/app/.next/build-manifest.json' ln -sf '/var/task/.next/export-marker.json' '/tmp/app/.next/export-marker.json' ln -sf '/var/task/.next/images-manifest.json' '/tmp/app/.next/images-manifest.json' ln -sf '/var/task/.next/next-minimal-server.js.nft.json' '/tmp/app/.next/next-minimal-server.js.nft.json' ln -sf '/var/task/.next/next-server.js.nft.json' '/tmp/app/.next/next-server.js.nft.json' ln -sf '/var/task/.next/package.json' '/tmp/app/.next/package.json' ln -sf '/var/task/.next/prerender-manifest.js' '/tmp/app/.next/prerender-manifest.js' ln -sf '/var/task/.next/prerender-manifest.json' '/tmp/app/.next/prerender-manifest.json' ln -sf '/var/task/.next/react-loadable-manifest.json' '/tmp/app/.next/react-loadable-manifest.json' ln -sf '/var/task/.next/required-server-files.json' '/tmp/app/.next/required-server-files.json' ln -sf '/var/task/.next/routes-manifest.json' '/tmp/app/.next/routes-manifest.json' ln -sf '/var/task/.next/static' '/tmp/app/.next/static' ln -sf '/var/task/.next/trace' '/tmp/app/.next/trace' ln -sf '/var/task/.next/types' '/tmp/app/.next/types' echo '[x-amplify-log][INFO] symlink creation complete path=.next' ln -sf '/var/task/.next/server/app' '/tmp/app/.next/server/app' ln -sf '/var/task/.next/server/app-paths-manifest.json' '/tmp/app/.next/server/app-paths-manifest.json' ln -sf '/var/task/.next/server/chunks' '/tmp/app/.next/server/chunks' ln -sf '/var/task/.next/server/font-manifest.json' '/tmp/app/.next/server/font-manifest.json' ln -sf '/var/task/.next/server/functions-config-manifest.json' '/tmp/app/.next/server/functions-config-manifest.json' ln -sf '/var/task/.next/server/interception-route-rewrite-manifest.js' '/tmp/app/.next/server/interception-route-rewrite-manifest.js' ln -sf '/var/task/.next/server/middleware-build-manifest.js' '/tmp/app/.next/server/middleware-build-manifest.js' ln -sf '/var/task/.next/server/middleware-manifest.json' '/tmp/app/.next/server/middleware-manifest.json' ln -sf '/var/task/.next/server/middleware-react-loadable-manifest.js' '/tmp/app/.next/server/middleware-react-loadable-manifest.js' ln -sf '/var/task/.next/server/next-font-manifest.js' '/tmp/app/.next/server/next-font-manifest.js' ln -sf '/var/task/.next/server/next-font-manifest.json' '/tmp/app/.next/server/next-font-manifest.json' ln -sf '/var/task/.next/server/pages-manifest.json' '/tmp/app/.next/server/pages-manifest.json' ln -sf '/var/task/.next/server/server-reference-manifest.js' '/tmp/app/.next/server/server-reference-manifest.js' ln -sf '/var/task/.next/server/server-reference-manifest.json' '/tmp/app/.next/server/server-reference-manifest.json' ln -sf '/var/task/.next/server/webpack-runtime.js' '/tmp/app/.next/server/webpack-runtime.js' echo '[x-amplify-log][INFO] symlink creation complete path=.next/server' echo '[x-amplify-log][INFO] Starting Server' node /tmp/app/server.js
Next.js App Router stores cache files under not .next/server/pages but .next/server/app.
So I think this run.sh should not use symlink via ln -sf '/var/task/.next/server/app' '/tmp/app/.next/server/app' but create dir like cp -r '/var/task/.next/server/app' '/tmp/app/.next/server' .
Additional info
- Next.js ver:
14.2.2 - GitHub Repo: https://github.com/Quramy/next-js-amplify-study
- My Amplify app id:
d25rciaxjd9k8z - Build artifact:
https://aws-amplify-prod-us-east-1-artifacts.s3.us-east-1.amazonaws.com/d25rciaxjd9k8z/main/0000000002/BUILD/artifacts.zip
Hi @Jay2113 san, we are also facing the same issue while processing ISR based on App Router. Any update about the investigation?
Our Next.js version is 14.2.1.
If needed any further info, please ask to me.
Hi Team, any update on this? So does this mean that we cannot use AWS amplify hosting for next js applications?
I get same error EROFS.
2024-07-03T02:45:18.887Z | START RequestId: f3d682f1-404a-4617-bd83-3ffeb19ac756 Version: $LATEST -- | --
| 2024-07-03T02:45:18.930Z | REPORT RequestId: f3d682f1-404a-4617-bd83-3ffeb19ac756 Duration: 42.62 ms Billed Duration: 43 ms Memory Size: 1024 MB Max Memory Used: 140 MB
| 2024-07-03T02:45:19.036Z | Failed to update prerender cache for /gpu [Error: EROFS: read-only file system, open '/tmp/app/.next/server/app/gpu.html'] {
| 2024-07-03T02:45:19.036Z | errno: -30,
| 2024-07-03T02:45:19.036Z | code: 'EROFS',
| 2024-07-03T02:45:19.036Z | syscall: 'open',
| 2024-07-03T02:45:19.036Z | path: '/tmp/app/.next/server/app/gpu.html'
| 2024-07-03T02:45:19.036Z | }
This is my gpu/page.tsx code
export const revalidate = 120; // in seconds
async function getData(): Promise<GpuListing[]> {
try {
const data = getDataFromS3("db/gpu.csv");
return data;
} catch (error) {
console.error('Error fetching data:', error);
return [];
}
}
export default async function Gpu() {
const data = await getData();
const datetime_str = await getDateTime();
return (
<div>
<header className="bg-white shadow">
<div className="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8">
<h1 className="text-3xl font-bold tracking-tight text-gray-900">GPU (Graphics Card)</h1>
</div>
</header>
<main>
<div className="mx-auto max-w-7xl py-6 sm:px-6 lg:px-8">
<DataTable columns={columns} data={data} />
</div>
</main>
</div>
)
}
Is there temporary workaround? Instead of using revalidate, can something else be used to trigger full page regeneration instead of ISR.
Hi team! I'm also facing the same issue using ISR with app router for our nextjs application. Is there any update about this, or estimated time when this issue will be fixed?
As Quramy mentioned, I've also have the same error log (read-only filesystem) and the run.sh seems only to be checking the pages router, but not the app router.
Hope this can be fixed soon!
Thanks!
We are working on a fairly large project. Can we get an update or at least confirmation that the team is working on it?
I have the same log output .
Failed to update prerender cache for /index [Error: EROFS: read-only file system, open '/tmp/app/.next/server/app/index.html']And it seems this issue occurs only for App Router pages.
I downloaded the build artifact and checked compute/run.sh. It seemas that Amplify Hosting creates the directory .next/server/pages as special.
#!/bin/bash unset AWS_ACCESS_KEY_ID unset AWS_SECRET_ACCESS_KEY unset AWS_SESSION_TOKEN mkdir -p '/tmp/app/.next/server/pages' echo '[x-amplify-log][INFO] starting copy' cp -r '/var/task/.next/server/pages' '/tmp/app/.next/server' echo '[x-amplify-log][INFO] copy server pages complete' cp -f /var/task/server.js /tmp/app/server.js echo '[x-amplify-log][INFO] symlink creation complete path=.next' ln -sf '/var/task/.next/server/app' '/tmp/app/.next/server/app' # other sym links node /tmp/app/server.jsFull run.sh Next.js App Router stores cache files under not .next/server/pages but .next/server/app. So I think this run.sh should not use symlink via
ln -sf '/var/task/.next/server/app' '/tmp/app/.next/server/app'but create dir likecp -r '/var/task/.next/server/app' '/tmp/app/.next/server'.Additional info
- Next.js ver:
14.2.2- GitHub Repo: https://github.com/Quramy/next-js-amplify-study
- My Amplify app id:
d25rciaxjd9k8z- Build artifact:
https://aws-amplify-prod-us-east-1-artifacts.s3.us-east-1.amazonaws.com/d25rciaxjd9k8z/main/0000000002/BUILD/artifacts.zip
Seeing your answer, I ended up having an idea, if permission is really the problem, what happens if I put Next to write the cache inside the "pages" folder then? I created a CacheHandler here, extending the same Next pattern, but adding an option to change the location of the page cache.
cache-handler.mjs
import FileSystemCache from 'next/dist/server/lib/incremental-cache/file-system-cache.js'
import path from 'path'
class CacheHandler extends FileSystemCache.default {
constructor(ctx) {
super(ctx)
}
getFilePath(pathname, kind) {
if (kind === 'app') {
return path.join(this.serverDistDir, 'pages', 'app', pathname)
}
return super.getFilePath(pathname, kind)
}
}
export default CacheHandler
next.config.mjs
export default {
cacheHandler: require.resolve('./cache-handler.mjs')
}
I followed the documentation here: https://nextjs.org/docs/app/api-reference/next-config-js/incrementalCacheHandlerPath.
And apparently it solved the problem here, it's not ideal, but as the solution was already said here and the amplify team didn't even move, I think it can solve some people's problems.