## TL;DR
Re-cut the version snapshot so versions.json and the versioned folders agree. The error means the versioned docs directory and the versions manifest disagree about what exists.

## Error
```text
Error: No docs version found.
```

## Steps
1. List the versioned content: check the versioned docs folders and print versions.json, for example with `ls docs_versioned_docs` and `cat versions.json`. Expected: you see which versions have folders and which the manifest claims.
2. If versions.json lists a version with no matching folder (or vice versa), delete the stale entry or restore the folder. Expected: manifest and folders describe the same set.
3. Re-cut the version cleanly with `npm run docusaurus docs:version 2.1.0` from a clean tree where the current docs are the ones you want snapshotted. Expected: the command creates matching folder and manifest entries.
4. Rebuild with `npm run build`. Expected: the version error is gone and the version dropdown lists the right versions.

## When to use
- The error appears immediately after a version bump or release
- versions.json was hand-edited
- A docs agent deleted old versions without updating the manifest

## When not to use
- You do not use Docusaurus versioning at all (check that versioning was not enabled accidentally)
- The error is about a missing sidebar file (different fix)
- The version dropdown shows wrong versions but the build succeeds (a manifest content issue)

## Tool compatibility
Docusaurus 2.x and 3.x docs plugin versioning. The versions.json format is stable across both.

### Variant phrasings
### no docs version found in CI but works locally
The versioned folders are gitignored or not committed. Commit versioned_docs, versioned_sidebars, and versions.json.

### error after renaming a version
Renaming requires updating versions.json, the folder names, and sidebar file names together. Re-cutting the version is safer than renaming by hand.

## Why it happens
Versioning is a snapshot: the manifest, the versioned docs folders, and the versioned sidebars must agree. Hand edits and partial deletions break the agreement, and the plugin refuses to guess which side is right.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_-v18zSrVLFaUrZ-vKFpapQ
