Skip to content

fix(docs): drop output: 'standalone' so the production docs build stops failing - #10652

Merged
os-elon merged 1 commit into
mainfrom
claude/issue-10638-docs-standalone-build
Aug 21, 2026
Merged

fix(docs): drop output: 'standalone' so the production docs build stops failing#10652
os-elon merged 1 commit into
mainfrom
claude/issue-10638-docs-standalone-build

Conversation

@os-elon

@os-elon os-elon commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Part of #10638. Deliberately not an auto-closing reference: this removes the only
code path that can raise the reported error, but the production deploy itself is not
verifiable from an agent seat, so a human should confirm the site actually serves before
that card closes. The canonical-host half of #10638 is owned elsewhere and is untouched here.

What the production build was doing

Error: ENOENT: no such file or directory, open
  '/vercel/path0/apps/docs/.next/next-server.js.nft.json'

The PM's stated mechanism is falsified — measured, not argued

The card's diagnosis was that a Turbopack build does not emit the node-file-trace
.nft.json set, making output: 'standalone' and Turbopack a contradiction inside one
config. That is false. Running the exact Vercel command
(cd ../.. && pnpm turbo run build --filter=@objectstack/docs, per apps/docs/vercel.json)
on a cold .next in a fresh worktree:

Observation Result
Engine used ▲ Next.js 16.3.1 (Turbopack) — the engine said not to emit traces
Build result Tasks: 2 successful, 2 total, exit 0, 4m19s
next-server.js.nft.json present, 270 KB
.nft.json files total 26
.next/standalone assembled successfully

Next's own source agrees: next/dist/build/adapter/build-complete.js:1369 reads
// Turbopack traces these itself, they are listed in the nft.json files.

So the failure does not reproduce locally, and the config pair is not in itself a
contradiction. Whatever suppresses the trace set is specific to Vercel's builder.

Why this change is still the right fix, on a verified code-path fact

The fix does not rest on the falsified mechanism. It rests on where the throw comes from,
read out of the installed next@16.3.1:

  1. The ENOENT is raised by copyTracedFilesnext/dist/build/utils.js:1106,
    handleTraceFiles(path.join(distDir, 'next-server.js.nft.json')).
  2. copyTracedFiles is reached only from writeStandaloneDirectory
    next/dist/build/index.js:2817.
  3. That call is gated only by if (config.output === 'standalone')
    next/dist/build/index.js:2814.

Removing the setting removes the only code path in a production build that opens that
file. This holds regardless of why the trace set is missing under Vercel.

And it costs nothing: .next/standalone has zero consumers in this repo
re-verified on a full clone (10555 commits, is-shallow-repositoryfalse), not the
shallow one the card was written from. No Dockerfile, workflow, script or config
references the path, and docker/Dockerfile does not build apps/docs at all. Vercel
does its own serverless packaging.

When this broke — the staleness window the maintainer asked for

Full history (the card could not date this from a shallow clone):

  • output: 'standalone' and Next 16 arrived together in the same commit,
    3124fe9788, 2026-01-19 ("Move documentation site to apps/docs"), at next@^16.1.3.
    So the pair is seven months old and was not newly introduced — it cannot by itself
    be the trigger.
  • next went 16.2.12 → 16.3.1 on 2026-08-17, in 7337f30495 (chore(deps)(deps): Bump the production-dependencies group with 19 updates #9212, a Dependabot
    production-dependency batch of 19 updates).

That bump is the only change to the build path in the window, which bounds the outage at
roughly 2026-08-17 → now (~4 days) — i.e. every docs PR merged since 2026-08-17,
including all of epic #10206, has never reached a reader. Worth confirming against the
first red production deploy in the Vercel dashboard.

Verification

Same command, same cold-.next protocol, at dce5c9fb61:

Run Result
Before (baseline) exit 0 — did not reproduce the failure
After (this commit) exit 0, Tasks: 2 successful, 2 total, Turbopack, 65s compile
.next/standalone after absent — the throwing path no longer executes
Rest of .next after intact (BUILD_ID, routes-manifest.json, server/, static/, …)

There is no red→green demonstration here, and this PR does not claim one — the red
baseline is not reproducible outside Vercel's builder.

Gates re-derived with node scripts/pm/dispatch-gates.mjs (no path args) after the
final commit dce5c9fb61; all seven named families plus the affected-package typecheck
and the NUL gate pass:

EXIT=0 :: pnpm check:changeset-gate-self-tests
EXIT=0 :: pnpm check:objectui-changeset
EXIT=0 :: pnpm check:test-source-alias
EXIT=0 :: pnpm check:type-source-resolution
EXIT=0 :: check-adr-0087-registration
EXIT=0 :: check-changeset-no-major
EXIT=0 :: check-empty-changeset
EXIT=0 :: pnpm --filter @objectstack/docs typecheck   (echoed `tsc --noEmit`)
EXIT=0 :: pnpm check:nul-bytes

Note for #10642 (reported, not fixed here)

While reproducing, one premise behind that card turned out to be wrong and is worth
correcting before anyone works it: the docs path filter at ci.yml:79-84 lists
content/** as well as apps/docs/**, so content-only commits do schedule
Build Docs. The filter is not the divergence. The remaining candidates are that CI runs
pnpm --filter @objectstack/docs build directly while Vercel goes through
turbo run build, and that CI restores apps/docs/.next/cache (ci.yml:1515) while
production builds cold. Neither explains an ENOENT that a cold local build cannot
reproduce; the likeliest remaining difference is that Vercel injects a build adapter
next/dist/server/config-shared.js:190 resolves adapterPath from
process.env.NEXT_ADAPTER_PATH, and build/index.js:2784-2814 runs that adapter's
onBuildComplete immediately before the standalone step, with an in-source comment
noting that output: 'standalone' may become disallowed when such an adapter is
configured. CI sets no adapter, which is exactly why CI stayed green.


Generated by Claude Code

…tops failing

The production build died at the end of `next build` with ENOENT on
`apps/docs/.next/next-server.js.nft.json`, so no page merged to `main` was
reaching the site.

That file is opened by `copyTracedFiles` (next/dist/build/utils.js), reached
only from `writeStandaloneDirectory` (next/dist/build/index.js), which Next
calls only under `if (config.output === 'standalone')`. Removing the setting
removes the only code path that performs that read.

Nothing in this repo consumes `.next/standalone`: no Dockerfile, workflow,
script or config references the path, and `docker/Dockerfile` does not build
apps/docs at all. Vercel does its own serverless packaging, so the setting had
no consumer on this deployment target.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GawRwpD44VwBDVy3hs77AX
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tooling labels Aug 21, 2026
@os-elon
os-elon marked this pull request as ready for review August 21, 2026 07:37
@os-elon
os-elon enabled auto-merge August 21, 2026 07:37
@os-elon
os-elon added this pull request to the merge queue Aug 21, 2026
Merged via the queue into main with commit 72d75eb Aug 21, 2026
24 checks passed
@os-elon
os-elon deleted the claude/issue-10638-docs-standalone-build branch August 21, 2026 07:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants