マルチバイト文字を含むパス、例えば /posts/[slug]
のような Dynamic Routes で /posts/応援してくれた皆さんに大切なお知らせ
という記事が投稿されるということはよくあることかと思います(当社調べ)。
このときに fetch
ではなく unstable_cache
+ Prisma を使って RDBMS からデータ取得するという場合に revalidateTag を脳死で下記のように指定するとエラーとなります。
const post = (slug: string) => unstable_cache( async () => { const post = await prisma.posts.findUnique(...) return post }, [`post-${slug}`], { tags: ['posts', `post-${slug}`] } )
Vercel 上で実際に得られたエラーログはこのような感じ
⨯ TypeError [ERR_INVALID_CHAR]: Invalid character in header content ["x-next-cache-tags"] at ServerResponse.setHeader (node:_http_outgoing:651:3) at f.setHeader (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:16:4791) at J.appendHeader (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:11:28821) at r3.renderToResponseWithComponentsImpl (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:3093) at runNextTicks (node:internal/process/task_queues:60:5) at listOnTimeout (node:internal/timers:538:9) at process.processTimers (node:internal/timers:512:7) at async r3.renderPageComponent (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:4780) at async r3.renderToResponseImpl (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:5363) at async r3.pipeImpl (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:16:17297) { code: 'ERR_INVALID_CHAR', page: '/data-fetching/revalidate-tag/%E3%83%9E%E3%83%AB%E3%83%81%E3%83%90%E3%82%A4%E3%83%88%E6%96%87%E5%AD%97' } TypeError [ERR_INVALID_CHAR]: Invalid character in header content ["x-next-cache-tags"] at ServerResponse.setHeader (node:_http_outgoing:651:3) at f.setHeader (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:16:4791) at J.appendHeader (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:11:28821) at r3.renderToResponseWithComponentsImpl (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:3093) at runNextTicks (node:internal/process/task_queues:60:5) at listOnTimeout (node:internal/timers:538:9) at process.processTimers (node:internal/timers:512:7) at async r3.renderPageComponent (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:4780) at async r3.renderToResponseImpl (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:17:5363) at async r3.pipeImpl (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:16:17297) { code: 'ERR_INVALID_CHAR', page: '/data-fetching/revalidate-tag/%E3%83%9E%E3%83%AB%E3%83%81%E3%83%90%E3%82%A4%E3%83%88%E6%96%87%E5%AD%97' } Error: Runtime exited with error: exit status 1 Runtime.ExitError
ちなみにこれローカルの yarn build && yarn start
では動くんですよね...
対処法として正しいかはわからないですが、下記のようなワークアラウンドで上記エラーを回避できます。
const post = (slug: string) => unstable_cache( async () => { const post = await prisma.posts.findUnique(...) return post }, [`post-${encodeURIComponent(slug)}`], { tags: ['posts', `post-${encodeURIComponent(slug)}`] } )
ウェブ界隈でエンジニアとして労働活動に励んでいる @gomi_ningen 個人のブログです