vercel/next.js · error · Error

Unsupported upgrade document

Error message

Unsupported upgrade document ${input.document}.

What it means

prepareUpgradeDocument copies an adoption document into the agent run directory. It supports two shapes: paths under 'docs/' copied from bundled docs, and 'skills/<name>/SKILL.md' paths fetched via the skills CLI. Any other document string has no supported resolution strategy, so it throws. This is an internal invariant over the future-defaults adoptionDoc data.

Solutions

  1. Fix the adoptionDoc path in packages/next/src/lib/upgrade/future-defaults.ts to start with 'docs/' or match 'skills/<name>/SKILL.md'
  2. If a new document kind is needed, extend prepareUpgradeDocument with a matching branch
  3. Check the warning 'Could not prepare upgrade document <doc>' in output to identify the offending document
  4. If all documents for a default fail, the run fails with 'Could not prepare adoption documents'; fix the first warning

Example fix

// before (future-defaults.ts)
adoptionDoc: ['skills/cache-components/skill.md']
// after
adoptionDoc: ['skills/cache-components/SKILL.md']
Defensive patterns

Strategy: validation

Validate before calling

function isSupportedDocument(doc) {
  return doc.startsWith('docs/') || /^skills\/.+\/SKILL\.md$/.test(doc)
}
if (!adoptionDoc.every(isSupportedDocument)) {
  throw new Error('bad adoptionDoc entry: ' + doc)
}

Type guard

function isSupportedDocument(doc: string): boolean {
  return doc.startsWith('docs/') || /^skills\/.+\/SKILL\.md$/.test(doc)
}

Prevention

When it happens

Trigger: future-defaults.ts lists an adoptionDoc entry that is neither 'docs/...' nor matches /^skills\/(.+)\/SKILL\.md$/; a typo, renamed skill, or new document kind added without extending prepareUpgradeDocument.

Common situations: A Next.js contributor adds a new future default with a mistyped adoptionDoc path (e.g. 'skill/x/SKILL.md' or 'skills/x/skill.md'), or a bundled docs file is renamed so both branches fail.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of vercel/next.js@34433fd12e (2026-09-20). Data as JSON: /api/errors/559e5a57bdad5a87. Report an issue: GitHub.

Appendix: source

Thrown at packages/next/src/cli/next-upgrade.ts:48

  bundledDocs: string
  nextVersion: string
  document: UpgradeDocument
}

async function prepareUpgradeDocument(
  input: PrepareUpgradeDocumentInput
): Promise<string> {
  if (input.document.startsWith('docs/')) {
    const path = input.document.slice('docs/'.length)
    const destination = join(input.runDirectory, input.document)
    await mkdir(dirname(destination), { recursive: true })
    await cp(join(input.bundledDocs, path), destination)
    return destination
  }

  const match = /^skills\/(.+)\/SKILL\.md$/.exec(input.document)
  if (!match) {
    throw new Error(`Unsupported upgrade document ${input.document}.`)
  }

  return prepareUpgradeSkill(input, match[1])
}

async function prepareUpgradeSkill(
  input: PrepareUpgradeDocumentInput,
  skill: string
): Promise<string> {
  const spawnCommand =
    require('next/dist/compiled/cross-spawn') as typeof import('next/dist/compiled/cross-spawn')
  const [command, ...runnerArgs] = getNpxCommand(input.directory).split(' ')
  const source =
    `https://github.com/vercel/next.js/tree/v${input.nextVersion}/skills/` +
    skill
  const args = [...runnerArgs, `skills@${SKILLS_CLI_VERSION}`, 'use', source]
  const skillDirectory = join(input.runDirectory, 'skills', skill)
  const instructionsPath = join(skillDirectory, 'PROMPT.md')

View on GitHub (pinned to 34433fd12e)