## TL;DR
The model is a separate package from spaCy itself; installing spaCy does not install any models. Run `python -m spacy download en_core_web_sm`, or pip-install the model wheel directly from the official spaCy models release page. Then `spacy.load("en_core_web_sm")` works.

## Error
```text
Can't find model 'en_core_web_sm'. It doesn't seem to be a Python package or a valid path to a data directory.
```

## Steps

1. Download the model with the spaCy CLI, using the same Python that runs your code:
```bash
python -m spacy download en_core_web_sm
```
Expected output: a download progress bar ending in a success message naming the installed version. If `python` and your project's interpreter differ, the model lands where your code cannot see it.

2. Verify the install:
```bash
python -m spacy validate
```
Expected output: a table listing `en_core_web_sm` with a version compatible with your spaCy version. A version-mismatch row here means you need step 3 with the right wheel.

3. If the CLI download is blocked (no network, locked-down env), pip-install the model wheel from the official spaCy models release page, picking the wheel whose version matches your spaCy major version:
```bash
pip install [model-wheel-url-from-spacy-models-release-page]
```
Expected output: pip reports the model package installed. The validate table in step 2 tells you which version you need.

4. Load it in code and confirm:
```python
import spacy
nlp = spacy.load("en_core_web_sm")
print(nlp.pipe_names)
```
Expected output: the pipeline component names, e.g. tagger, parser, ner. No can't-find-model error.

## When to use
- `spacy.load("en_core_web_sm")` raises the can't-find-model error
- A fresh virtualenv, container, or CI runner runs spaCy code for the first time
- The error appears after upgrading spaCy (the old model no longer matches)

## When not to use
- The model loads but gives bad results (that is a model-quality question, not installation)
- You need a different language (download that language's model instead)
- The error names a custom model path (check the path exists)

## Variant phrasings

### E050 Can't find model 'en_core_web_md'
Same fix, larger model. `python -m spacy download en_core_web_md`, and make sure you have the disk space (the md and lg models are much bigger).

### model worked yesterday, fails today in CI
CI rebuilt the environment without the model install step. Add the download to your build script or bake the model into the image.

## Why it happens
spaCy ships the library and the trained models as separate packages so installs stay small. `spacy.load("en_core_web_sm")` looks for an installed package or a data directory by that name; with neither present, it raises instead of guessing. Upgrades break it because each model release targets a specific spaCy version.

## Edge cases
- There is no pip extra like spacy[en_core_web_sm]; the bracket extra does not exist. Use the CLI or the wheel URL.
- Corporate proxies can break the CLI downloader while pip works; the wheel URL is the fallback.
- Loading by package name vs by path: `spacy.load("en_core_web_sm")` and `spacy.load("[path-to-model]")` both work, but only the package form survives a reinstall.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_XTL5Q2aDCT4zWaxra9PvnA
