Missing Build System Broke Entry Point | Generated by AI
Summary
What happened
You renamed the project from timesheet to tt (both the directory and pyproject.toml name field). After that, uv run tt failed with:
error: Failed to spawn: `tt`
Caused by: No such file or directory (os error 2)
Root cause
The pyproject.toml was missing a [build-system] declaration. When uv sync runs without one, it emits this warning (which was easy to miss):
warning: Skipping installation of entry points (`project.scripts`) for package `tt`
because this project is not packaged; to install entry points, set `tool.uv.package = true`
or define a `build-system`
Without a build system, uv installs the dependencies but never registers the CLI entry point (tt = "tt.cli:main"). So the tt command simply doesn’t exist in the venv’s bin/, and the shell can’t find it.
What was changed
pyproject.toml — two edits:
- Added a build system (hatchling):
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
- Replaced the old setuptools package discovery with hatch’s equivalent:
# Before (setuptools — inert without setuptools as build-backend)
[tool.setuptools.packages.find]
include = ["tt*"]
exclude = ["data*", "input*"]
# After (hatchling)
[tool.hatch.build.targets.wheel]
packages = ["tt"]
Then uv sync rebuilt the package and registered the entry point.
Why it probably worked before
The old project at /Users/lzwjava/projects/timesheet likely had a cached venv from a time when uv sync or uv pip install -e . was run with the package in installable mode, or tool.uv.package = true was set. When you renamed/moved the project, uv sync re-resolved from scratch and hit the missing build-system gap.
Options if you ever need them
Instead of adding [build-system], you could also have added this to pyproject.toml:
[tool.uv]
package = true
This tells uv to treat the project as a package and install entry points even without a formal build backend. But using hatchling is the more standard approach.