|
1 | 1 | # Troubleshooting |
2 | 2 |
|
3 | | -- `uv sync` fails: check `.python-version` and network |
4 | | -- Non-empty target dir: pass `--force` |
5 | | -- Offline scaffold: ensure cache warmed or use `file://` fixtures |
| 3 | +Common issues when scaffolding projects with `create-awesome-python-app`. |
| 4 | + |
| 5 | +## Python version mismatch |
| 6 | + |
| 7 | +**Symptoms:** The CLI exits immediately with a Python version error. |
| 8 | + |
| 9 | +**Requirement:** Python **>= 3.12** |
| 10 | + |
| 11 | +```bash |
| 12 | +python --version |
| 13 | +``` |
| 14 | + |
| 15 | +**Switch versions:** |
| 16 | + |
| 17 | +- [uv](https://docs.astral.sh/uv/): `uv python install 3.12 && uv python pin 3.12` |
| 18 | +- [pyenv](https://github.com/pyenv/pyenv): `pyenv install 3.12 && pyenv local 3.12` |
| 19 | +- [mise](https://mise.jdx.dev/): `mise use python@3.12` |
| 20 | + |
| 21 | +The workspace pin file is `.python-version` (currently `3.12`). Generated projects |
| 22 | +inherit `requires-python` from their template. |
| 23 | + |
| 24 | +## Non-empty target directory |
| 25 | + |
| 26 | +**Symptoms:** Scaffolding aborts with `CPA_NON_EMPTY_TARGET_DIR` or |
| 27 | +`Target directory is not empty: <path>`. |
| 28 | + |
| 29 | +**Cause:** CPA refuses to scaffold into a directory that already contains files, |
| 30 | +to avoid overwriting user data. |
| 31 | + |
| 32 | +**Fix:** |
| 33 | + |
| 34 | +```bash |
| 35 | +# Scaffold into a new directory (default: my-project) |
| 36 | +uvx create-awesome-python-app my-new-app -t fastapi-starter --no-interactive |
| 37 | + |
| 38 | +# Or allow scaffolding into a non-empty directory |
| 39 | +uvx create-awesome-python-app existing-dir -t fastapi-starter --force --no-interactive |
| 40 | +``` |
| 41 | + |
| 42 | +Use `--force` / `-f` only when you intend to merge into an existing tree. |
| 43 | + |
| 44 | +## Catalog and slug errors |
| 45 | + |
| 46 | +**Symptoms:** `Invalid catalog slug: '<slug>'. Run --list-templates / --list-addons or pass a full URL.` |
| 47 | + |
| 48 | +**Cause:** The `-t`, `--addons`, or `--extend` value does not match any entry in |
| 49 | +`templates.json` from [cpa-templates](https://github.com/Create-Python-App/cpa-templates). |
| 50 | + |
| 51 | +**Fix:** |
| 52 | + |
| 53 | +```bash |
| 54 | +# List official templates |
| 55 | +uvx create-awesome-python-app --list-templates |
| 56 | + |
| 57 | +# List extensions (optionally filtered by template) |
| 58 | +uvx create-awesome-python-app --list-addons -t fastapi-starter |
| 59 | + |
| 60 | +# Use the exact slug from the catalog |
| 61 | +uvx create-awesome-python-app my-app -t fastapi-starter --no-interactive |
| 62 | +``` |
| 63 | + |
| 64 | +**Tips:** |
| 65 | + |
| 66 | +- Slugs are case-sensitive (`fastapi-starter`, not `FastAPI-Starter`). |
| 67 | +- Pass a full URL when using a fork or local template instead of a catalog slug. |
| 68 | +- Override the catalog source for forks or offline testing: |
| 69 | + |
| 70 | +```bash |
| 71 | +CPA_CATALOG_URL="file:///path/to/cpa-templates/templates.json" \ |
| 72 | + uvx create-awesome-python-app my-app -t fastapi-starter --no-interactive |
| 73 | +``` |
| 74 | + |
| 75 | +If the catalog fetch fails but a disk cache exists, CPA falls back to the cached |
| 76 | +copy and prints a yellow warning. With no cache and no fixture, scaffolding fails |
| 77 | +with `Failed to load template catalog`. |
| 78 | + |
| 79 | +## Template URL not found |
| 80 | + |
| 81 | +**Symptoms:** Scaffolding fails with HTTP 404, `repository not found`, or |
| 82 | +`file source not found` (`CPA_FILE`). |
| 83 | + |
| 84 | +**Tips:** |
| 85 | + |
| 86 | +- Registry templates use slugs: `uvx create-awesome-python-app my-app -t fastapi-starter` |
| 87 | +- Custom URLs must be valid GitHub HTTPS URLs, `git@` SSH targets, or `file://` paths |
| 88 | +- Pin a branch, tag, or commit with `?ref=`: |
| 89 | + |
| 90 | +```bash |
| 91 | +uvx create-awesome-python-app my-app \ |
| 92 | + -t "https://github.com/Create-Python-App/cpa-templates?subdir=templates/fastapi-starter&ref=main" |
| 93 | +``` |
| 94 | + |
| 95 | +- Test a local template checkout: |
| 96 | + |
| 97 | +```bash |
| 98 | +uvx create-awesome-python-app my-app \ |
| 99 | + -t "file:///path/to/cpa-templates?subdir=templates/fastapi-starter" |
| 100 | +``` |
| 101 | + |
| 102 | +- List official templates: `uvx create-awesome-python-app --list-templates` |
| 103 | + |
| 104 | +For reproducible CI builds, pin a full 40-character commit SHA and set |
| 105 | +`CPA_STRICT_REPRO=1` so non-SHA `ref` values are rejected. |
| 106 | + |
| 107 | +## Cache location and inspection |
| 108 | + |
| 109 | +By default, CPA caches the template catalog and git repos under `~/.cache/cpa`. |
| 110 | +The CLI exposes this via: |
| 111 | + |
| 112 | +```bash |
| 113 | +uvx create-awesome-python-app cache dir # print the cache root |
| 114 | +uvx create-awesome-python-app cache list # entries: id, url, ref, last fetched, sha, size |
| 115 | +uvx create-awesome-python-app cache verify # run git fsck on every entry |
| 116 | +uvx create-awesome-python-app cache verify <id> # verify one entry |
| 117 | +uvx create-awesome-python-app cache clean # remove all repo entries |
| 118 | +uvx create-awesome-python-app cache clean <id> # remove one entry by id |
| 119 | +uvx create-awesome-python-app cache clean --catalog # also clear catalog/templates.json cache |
| 120 | +uvx create-awesome-python-app cache outdated # compare local SHAs to remote tips |
| 121 | +uvx create-awesome-python-app cache update # refresh all cached repos |
| 122 | +uvx create-awesome-python-app cache update <id> # refresh one entry |
| 123 | +uvx create-awesome-python-app cache doctor # check git, network, cache dir, integrity |
| 124 | +``` |
| 125 | + |
| 126 | +Layout: |
| 127 | + |
| 128 | +```text |
| 129 | +~/.cache/cpa/ |
| 130 | + catalog/ |
| 131 | + templates.json |
| 132 | + repos/ |
| 133 | + <cache-key>/ |
| 134 | + .cpa-cache.json |
| 135 | + ... |
| 136 | +``` |
| 137 | + |
| 138 | +If a scaffold "looks weird" and you suspect a stale cache, the first diagnostic |
| 139 | +step is `cache verify`. If any entry fails, `cache clean` and re-run. Use |
| 140 | +`cache outdated` + `cache update` when you need newer template content without |
| 141 | +a full re-download. |
| 142 | + |
| 143 | +## Forcing a fresh fetch |
| 144 | + |
| 145 | +```bash |
| 146 | +# Force a re-fetch of templates.json and template repos on every run. |
| 147 | +uvx create-awesome-python-app my-app -t fastapi-starter --no-cache --no-interactive |
| 148 | + |
| 149 | +# Disable git pull on cache hit (use the local copy as-is). |
| 150 | +uvx create-awesome-python-app my-app -t fastapi-starter --offline --no-interactive |
| 151 | + |
| 152 | +# Control refresh policy explicitly (default: stale). |
| 153 | +uvx create-awesome-python-app my-app -t fastapi-starter --refresh always --no-interactive |
| 154 | +uvx create-awesome-python-app my-app -t fastapi-starter --refresh manual --no-interactive |
| 155 | + |
| 156 | +# Pin the cache to a project-local directory (useful in CI). |
| 157 | +CPA_CACHE_DIR="$PWD/.cpa-cache" uvx create-awesome-python-app my-app -t fastapi-starter --no-interactive |
| 158 | + |
| 159 | +# Or use the CLI flag (sets CPA_CACHE_DIR internally) |
| 160 | +uvx create-awesome-python-app my-app -t fastapi-starter --cache-dir "$PWD/.cpa-cache" --no-interactive |
| 161 | +``` |
| 162 | + |
| 163 | +### CPA_* environment variables |
| 164 | + |
| 165 | +| Variable | Purpose | |
| 166 | +|----------|---------| |
| 167 | +| `CPA_CACHE_DIR` | Override cache root (default `~/.cache/cpa`) | |
| 168 | +| `CPA_CATALOG_URL` | Override catalog URL (default raw GitHub `templates.json`) | |
| 169 | +| `CPA_NO_CATALOG_CACHE` | Set by `--no-cache`; skip in-memory/disk catalog cache | |
| 170 | +| `CPA_REFRESH` | Refresh mode: `always`, `stale` (default), or `manual` | |
| 171 | +| `CPA_REFRESH_AFTER_HOURS` | Hours before a stale entry is refreshed (default `24`) | |
| 172 | +| `CPA_STRICT_REPRO` | Require full 40-char SHA in `?ref=` for reproducibility | |
| 173 | +| `CPA_STRICT_VERSION` | Fail when CLI is older than latest PyPI release | |
| 174 | +| `CPA_SKIP_GIT` | Skip `git init` in generated project (testing) | |
| 175 | +| `CPA_CATALOG_FIXTURE` | Load bundled catalog fixture (testing) | |
| 176 | +| `CPA_TEMPLATES_ROOT` | Local `cpa-templates` checkout for integration tests | |
| 177 | + |
| 178 | +`--no-cache` sets `CPA_NO_CATALOG_CACHE=1` and forces `--refresh always` for |
| 179 | +template repos. `--offline` uses cached repos only; a cache miss raises |
| 180 | +`CPA_OFFLINE`. |
| 181 | + |
| 182 | +See also: [MIGRATION.md](./MIGRATION.md) for keeping scaffolded projects up to date. |
| 183 | + |
| 184 | +## uv sync failures |
| 185 | + |
| 186 | +**Symptoms:** Scaffolding copies files but fails during `uv sync` in the generated |
| 187 | +project, or exits with `CPA_ABORTED`. |
| 188 | + |
| 189 | +**Cause:** The template includes a `pyproject.toml` and CPA runs `uv sync` by |
| 190 | +default to install dependencies. |
| 191 | + |
| 192 | +**Fix:** |
| 193 | + |
| 194 | +1. Confirm `uv` is installed and on `PATH`: |
| 195 | + |
| 196 | +```bash |
| 197 | +uv --version |
| 198 | +create-awesome-python-app --info |
| 199 | +``` |
| 200 | + |
| 201 | +1. Check the generated project's `.python-version` and `requires-python` in |
| 202 | + `pyproject.toml` match your interpreter. |
| 203 | + |
| 204 | +1. Retry manually inside the project: |
| 205 | + |
| 206 | +```bash |
| 207 | +cd my-app |
| 208 | +uv sync |
| 209 | +``` |
| 210 | + |
| 211 | +1. If you only need the file tree (no install), skip sync during scaffold: |
| 212 | + |
| 213 | +```bash |
| 214 | +uvx create-awesome-python-app my-app -t fastapi-starter --no-install --no-interactive |
| 215 | +``` |
| 216 | + |
| 217 | +1. For network or index issues, retry with verbose logging or behind a proxy; |
| 218 | + CPA does not wrap `uv` output -- read the `uv sync` error directly. |
| 219 | + |
| 220 | +## Git clone failures |
| 221 | + |
| 222 | +**Symptoms:** `git clone failed` (`CPA_GIT`), `git executable not found`, or |
| 223 | +`offline mode: cache miss` (`CPA_OFFLINE`). |
| 224 | + |
| 225 | +**Cause:** CPA clones template and extension repos from GitHub (or custom URLs) |
| 226 | +into the local cache before copying layers. |
| 227 | + |
| 228 | +**Fix:** |
| 229 | + |
| 230 | +1. Confirm git is available: |
| 231 | + |
| 232 | +```bash |
| 233 | +git --version |
| 234 | +create-awesome-python-app --info |
| 235 | +``` |
| 236 | + |
| 237 | +1. Warm the cache while online, then scaffold offline: |
| 238 | + |
| 239 | +```bash |
| 240 | +uvx create-awesome-python-app my-app -t fastapi-starter --no-interactive |
| 241 | +uvx create-awesome-python-app my-app2 -t fastapi-starter --offline --no-interactive |
| 242 | +``` |
| 243 | + |
| 244 | +1. For private repos, ensure SSH keys or credentials work outside CPA: |
| 245 | + |
| 246 | +```bash |
| 247 | +git ls-remote git@github.com:your-org/your-template.git |
| 248 | +``` |
| 249 | + |
| 250 | +1. Clear a corrupted cache entry and retry: |
| 251 | + |
| 252 | +```bash |
| 253 | +uvx create-awesome-python-app cache verify |
| 254 | +uvx create-awesome-python-app cache clean |
| 255 | +uvx create-awesome-python-app my-app -t fastapi-starter --no-interactive |
| 256 | +``` |
| 257 | + |
| 258 | +1. Use `file://` URLs to scaffold from a local checkout without network access. |
| 259 | + |
| 260 | +## incompatibleWith errors |
| 261 | + |
| 262 | +**Symptoms:** `Incompatible extension combination from cpa.config.json: 'foo' <-> 'bar'. Remove one of each conflicting pair and retry.` |
| 263 | + |
| 264 | +**Cause:** Two or more selected extensions declare each other in `incompatibleWith` |
| 265 | +(either in `cpa.config.json` or in catalog metadata). CPA validates addon/extend |
| 266 | +layers before merging. |
| 267 | + |
| 268 | +**Fix:** |
| 269 | + |
| 270 | +1. List extensions and read their descriptions: |
| 271 | + |
| 272 | +```bash |
| 273 | +uvx create-awesome-python-app --list-addons -t fastapi-starter |
| 274 | +``` |
| 275 | + |
| 276 | +1. Remove one extension from each conflicting pair in `--addons` / `--extend`. |
| 277 | + |
| 278 | +1. When authoring extensions, set `incompatibleWith` in `cpa.config.json`: |
| 279 | + |
| 280 | +```json |
| 281 | +{ |
| 282 | + "name": "postgres", |
| 283 | + "incompatibleWith": ["sqlite"] |
| 284 | +} |
| 285 | +``` |
| 286 | + |
| 287 | +Matches use each layer's `name` field (slug-like id), not the catalog display name. |
| 288 | + |
| 289 | +## `--set` values with spaces |
| 290 | + |
| 291 | +When passing custom options that contain spaces, quote the entire `key=value` pair: |
| 292 | + |
| 293 | +```bash |
| 294 | +uvx create-awesome-python-app my-app -t fastapi-starter \ |
| 295 | + --set 'projectName=My Awesome Project' \ |
| 296 | + --no-interactive |
| 297 | +``` |
| 298 | + |
| 299 | +Multiple `--set` flags merge into the Jinja context alongside `cpa.config.json` |
| 300 | +defaults. |
| 301 | + |
| 302 | +## CI reproduction tips |
| 303 | + |
| 304 | +Reproduce scaffold failures locally the way CI does: |
| 305 | + |
| 306 | +```bash |
| 307 | +# Match the test workflow environment |
| 308 | +git clone https://github.com/Create-Python-App/create-python-app.git |
| 309 | +cd create-python-app |
| 310 | +git clone https://github.com/Create-Python-App/cpa-templates.git ../cpa-templates |
| 311 | + |
| 312 | +uv sync --group dev |
| 313 | +export CPA_TEMPLATES_ROOT="$(cd ../cpa-templates && pwd)" |
| 314 | +export CPA_SKIP_GIT=1 |
| 315 | +export CPA_CACHE_DIR="$PWD/.cpa-cache-ci" |
| 316 | +export CPA_NO_CATALOG_CACHE=1 |
| 317 | + |
| 318 | +uv run create-awesome-python-app test-app \ |
| 319 | + -t fastapi-starter \ |
| 320 | + --no-interactive \ |
| 321 | + --cache-dir "$CPA_CACHE_DIR" |
| 322 | +``` |
| 323 | + |
| 324 | +**Checklist:** |
| 325 | + |
| 326 | +- Use `--no-interactive` in CI (interactive prompts are skipped when `CI=true`). |
| 327 | +- Pin `CPA_CACHE_DIR` to a workspace path for cache reuse across steps. |
| 328 | +- Set `CPA_CATALOG_URL` to a `file://` catalog when testing forks offline. |
| 329 | +- Run `create-awesome-python-app --info` in bug reports (Python, uv, git versions). |
| 330 | +- Run `create-awesome-python-app cache doctor` before blaming template content. |
| 331 | +- Use `CPA_STRICT_REPRO=1` and a full commit SHA in `?ref=` for deterministic builds. |
| 332 | + |
| 333 | +## Distribution channels |
| 334 | + |
| 335 | +Install the CLI from PyPI or run it ephemerally with uv: |
| 336 | + |
| 337 | +```bash |
| 338 | +# Ephemeral (recommended for end users) |
| 339 | +uvx create-awesome-python-app@latest my-app |
| 340 | + |
| 341 | +# Pin a release |
| 342 | +uvx create-awesome-python-app@0.1.0 my-app --template fastapi-starter --no-interactive |
| 343 | + |
| 344 | +# Install into the active environment |
| 345 | +uv tool install create-awesome-python-app |
| 346 | +create-awesome-python-app my-app -t fastapi-starter --no-interactive |
| 347 | +``` |
| 348 | + |
| 349 | +Other channels (same package, different installers): |
| 350 | + |
| 351 | +| Channel | Install | |
| 352 | +|---------|---------| |
| 353 | +| **PyPI** | `uv tool install create-awesome-python-app` or `uvx create-awesome-python-app` | |
| 354 | +| **Homebrew** | `brew tap Create-Python-App/tap && brew install create-awesome-python-app` | |
| 355 | +| **AUR** | `yay -S create-awesome-python-app` | |
| 356 | +| **Docker** | `docker run --rm -v "${PWD}:/app" -w /app ulisesjeremias/create-awesome-python-app my-app` | |
| 357 | + |
| 358 | +Verify the installed version: |
| 359 | + |
| 360 | +```bash |
| 361 | +create-awesome-python-app --version |
| 362 | +uvx create-awesome-python-app@latest --version |
| 363 | +``` |
| 364 | + |
| 365 | +If behavior differs between `uvx` and a global install, compare versions and |
| 366 | +clear the uv tool cache. See [DISTRIBUTION_SETUP.md](./DISTRIBUTION_SETUP.md) for |
| 367 | +maintainer release workflow. |
0 commit comments