Skip to content

Track stable Next.js fix for intermittent docs 404 deployment race #4525

Description

@marius-kilocode

Summary

The Kilo documentation deployment can intermittently fail during the Vercel onBuildComplete hook with a missing docs/404.html. The application compilation and static page generation finish successfully; the failure occurs while the Vercel adapter materializes static outputs.

This issue tracks upgrading the docs site to the first stable Next.js release containing vercel/next.js#95681. That upstream change fixes the actual duplicate-output bug. Until then, a cache-free redeployment is an operational recovery only and does not eliminate the race.

Related Kilo PR where the failure was observed: Kilo-Org/kilocode#12197.

Sanitized failure signature

Running onBuildComplete from Vercel
Failed to run onBuildComplete from Vercel

Error: ENOENT: no such file or directory, chmod
<checkout>/packages/kilo-docs/.next/output/static/docs/404.html

No application compilation error precedes this. Next.js reports that all static pages were generated before the hook fails.

Root cause

The affected build uses Next.js 16.2.9, a Pages Router custom 404 page, and basePath: "/docs":

Next.js 16.2.9 adds the same auto-static 404 output twice:

  1. The normal auto-static page path adds /404 to outputs.staticFiles: build-complete.ts lines 904-912.
  2. The later error-page fallback path adds /404 again without checking whether that pathname was already emitted: build-complete.ts lines 1890-1920.

Both entries have the same pathname and source file:

/docs/404 -> <checkout>/packages/kilo-docs/.next/server/pages/404.html
/docs/404 -> <checkout>/packages/kilo-docs/.next/server/pages/404.html

The Vercel adapter handles static outputs concurrently and maps both entries to the same destination. Its copy helper removes the destination before copying:

A possible interleaving is:

copy A writes docs/404.html
copy B removes docs/404.html
copy A attempts chmod on docs/404.html
copy A receives ENOENT

This is timing-dependent. Restored build cache state changes filesystem timing, which explains why one cached deployment failed while a subsequent cache-free deployment of the same commit succeeded. Clearing the cache does not fix the duplicate outputs.

The diagnosis matches the upstream report exactly. The upstream PR states that duplicate static entries cause concurrent file-operation races in the Vercel adapter:

Deterministic reproduction

The Vercel ENOENT itself is timing-dependent, but the invalid duplicate adapter output is deterministic.

  1. Check out Kilo commit 0f7c46c15bcff2fde243f7af9db2ec301070ef98 or another commit using Next.js 16.2.9 with the same docs 404 page.
  2. Install dependencies from the lockfile.
  3. Create packages/kilo-docs/adapter-debug.cjs:
module.exports = {
  name: "diagnostic",
  onBuildComplete({ outputs }) {
    console.log(
      outputs.staticFiles.filter(
        (output) => output.pathname === "/docs/404",
      ),
    )
  },
}
  1. Run the docs build with the diagnostic adapter:
NEXT_ADAPTER_PATH="$PWD/packages/kilo-docs/adapter-debug.cjs" \
  bun run --cwd packages/kilo-docs build
  1. Observe two identical /docs/404 entries in outputs.staticFiles.
  2. Delete the diagnostic adapter after reproduction.

Release status at time of filing

  • Project lockfile resolves Next.js 16.2.9.
  • Stable Next.js 16.2.10 was published before the upstream fix merged and still contains the duplicate-output logic.
  • 16.3.0-canary.85 contains the fix, but moving the docs site to a broad canary is not justified for this intermittent deployment issue.
  • The upstream fix merged on July 13, 2026. Wait for a stable release that contains commit db1f3a64daf26f8c3866cc7d6e96b6c3f70d5b6b.

Implementation once released

  1. Identify the first stable Next.js version containing the upstream fix commit.
  2. Upgrade next in packages/kilo-docs/package.json and regenerate bun.lock.
  3. Repeat the diagnostic adapter reproduction and confirm exactly one /docs/404 static output.
  4. Run the docs build, typecheck, tests, and lint.
  5. Verify a Vercel preview deployment that restores its normal build cache completes onBuildComplete successfully.
  6. Remove any temporary workaround if one was introduced before the stable upgrade.

Acceptance criteria

  • The docs package uses a stable Next.js release containing #95681.
  • outputs.staticFiles contains only one /docs/404 entry.
  • Cached and cache-free Vercel preview builds complete successfully.
  • The custom static 404 page still renders with an HTTP 404 response.

Workarounds to avoid unless deployment becomes repeatedly blocked

  • Do not remove the custom 404 page.
  • Do not add getStaticProps solely to change the page from a static-file output to a prerender output; that avoids the race but changes deployment behavior.
  • Do not carry a local patch of compiled Next.js output if waiting for the stable release remains operationally acceptable.
  • Do not pin the docs site to a broad Next.js canary solely for this fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdependenciesPull requests that update a dependency file

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions