Preflight
Motivation
Dependabot PR #49 proposed bumping next from 14.2.35 to 16.3.5 with a one-line manifest change and zero source changes. Both CI legs fail for reasons that can only be fixed by source changes, so the PR cannot go green in its current shape — it is a framework migration wearing a bump's clothing. Two major versions (14 → 15 → 16) separate the current runtime from the target, and the repo gains nothing from keeping the bump open while the migration work is unowned. The PR was closed; this issue tracks the real work.
Evidence: #49 (comment) (reading of head 58edfb50117, CI job logs quoted verbatim there).
Scope
In scope:
- The four source-level breakages listed in the acceptance criteria below.
- One replacement upgrade PR carrying the manifest/lock bump plus those source changes.
Out of scope:
- Other dependency upgrades bundled into the same PR.
- Redesigning the affected route or its rendering model beyond what Next 16 forces.
Acceptance criteria
next lint is replaced. It was removed in Next 15; the test leg runs it and lint is now parsed as a project directory (Invalid project directory provided, no such directory: .../doc/lint, job 103580513817). Move linting to a standalone ESLint invocation wired into CI.
- The parallel route
app/[locale]/work/[id]/@directory/ gets a default.js boundary. Turbopack treats its absence as a hard error: Missing required default.js file for parallel route at /[locale]/work/[id]/@directory (job 103580513625).
- The CSS file the new parser rejects is fixed. Under 14 the old parser warned through; under 16
Parsing CSS source code failed is fatal to the build.
- The fatal
Module not found: Can't resolve 'proxy-agent' is resolved. It is an optional dependency reached from services/… code via new (require('proxy-agent'))(proxy); 16's bundler treats the unresolved require as fatal where 14 left it as a dynamic require. Either declare the dependency explicitly or guard the require.
- The replacement PR is green on
test, docker-build, CodeQL (javascript-typescript), Dependency review, and OpenSSF Scorecard, and is approved per CODEOWNERS before merge.
Validation plan
- CI evidence on the replacement PR: linked
test and docker-build job runs, both success.
- Follow the Next.js 14 → 15 and 15 → 16 upgrade guides (codemods where applicable) in order; record in the PR body which codemods were run and which breakages needed manual changes.
- Reviewer approval from a CODEOWNER who is not the PR author (this repo enforces
require_last_push_approval and required_conversation_resolution; approval must post-date the final push).
Affected component
Next.js web app runtime, services/collaboration bundling, CI lint step.
Dependencies and risks
Preflight
Motivation
Dependabot PR #49 proposed bumping
nextfrom 14.2.35 to 16.3.5 with a one-line manifest change and zero source changes. Both CI legs fail for reasons that can only be fixed by source changes, so the PR cannot go green in its current shape — it is a framework migration wearing a bump's clothing. Two major versions (14 → 15 → 16) separate the current runtime from the target, and the repo gains nothing from keeping the bump open while the migration work is unowned. The PR was closed; this issue tracks the real work.Evidence: #49 (comment) (reading of head
58edfb50117, CI job logs quoted verbatim there).Scope
In scope:
Out of scope:
Acceptance criteria
next lintis replaced. It was removed in Next 15; thetestleg runs it andlintis now parsed as a project directory (Invalid project directory provided, no such directory: .../doc/lint, job103580513817). Move linting to a standalone ESLint invocation wired into CI.app/[locale]/work/[id]/@directory/gets adefault.jsboundary. Turbopack treats its absence as a hard error:Missing required default.js file for parallel route at /[locale]/work/[id]/@directory(job103580513625).Parsing CSS source code failedis fatal to the build.Module not found: Can't resolve 'proxy-agent'is resolved. It is an optional dependency reached fromservices/…code vianew (require('proxy-agent'))(proxy); 16's bundler treats the unresolved require as fatal where 14 left it as a dynamic require. Either declare the dependency explicitly or guard the require.test,docker-build,CodeQL (javascript-typescript),Dependency review, andOpenSSF Scorecard, and is approved per CODEOWNERS before merge.Validation plan
testanddocker-buildjob runs, both success.require_last_push_approvalandrequired_conversation_resolution; approval must post-date the final push).Affected component
Next.js web app runtime,
services/collaborationbundling, CI lint step.Dependencies and risks
67 vulnerabilities (53 moderate, 14 high)from the pre-build audit.