uv tool run cannot find the executable: separate package and command names
By ON Lab · Sources checked November 8, 2026
When uv reports that a package provides a different executable, keep the package name after --from and put the actual command after it. For the reported toolong/tl case, the documented form is uv tool run --from toolong tl. Verify both names against the publisher’s instructions before running downloaded code. A package that installed successfully can still lack the command you requested.
Start with the exact error, not another installation
A reader reported that uv tool run toolong could not find an executable named toolong, while the error listed tl. The distribution and the command had different names. This is a concrete naming problem, not evidence that the tool needs reinstalling globally or that the project environment is broken.
Record the full command, the uv version, and the complete error. Look for the package named in the message and the list of available executables. If the failure instead concerns downloading a distribution, finding Python, importing a module, or opening an input file, use that earlier or later failure as the starting point. The same visible word “not found” can refer to different objects.
| Observed result | What to check next |
|---|---|
| The package installed; requested executable is absent; another name is listed | Compare distribution and command names, then supply the verified pair |
| No package version can be resolved | Check the requested source, version and network conditions; a command rename does not repair resolution |
| The command starts but cannot import a project module | Check whether an isolated tool is the intended environment |
| The command starts but rejects a filename or option | Read that tool’s own help and verify its arguments |
Separate three names before changing the command
Write down the distribution name, executable name and input filename on separate lines. In the reported example they are toolong, tl and the reader’s log file. Do not replace all three just because the first invocation failed. The distribution identifies what supplies the command; the executable identifies what should start; the remaining arguments belong to the started program.
# Documented naming form; may download and execute the chosen tool
uv tool run --from toolong tl
# uvx is the tool-run alias
uvx --from toolong tl
These forms explain the mapping; this guide did not download or execute toolong. Add an actual input only after checking its command syntax and confirming that it is appropriate to give that tool the file. Installing a similarly named package is not a reliable way to discover which publisher owns a command.
A small offline reproduction with a local wheel
We tested the naming boundary using uv 0.13.7 on macOS with an existing Python interpreter. The test distribution was named desk-demo-dist, but it declared just one console entry point, desk-demo. Its entire executable function printed a fixed marker. It had no third-party dependencies, made no network requests and did not read documents.
The wheel was assembled locally with ordinary wheel metadata and a record of its files. Its entry point declaration and function were:
[console_scripts]
desk-demo = desk_demo:main
def main():
print("DESK_DEMO_OK: local distribution and command names differ")
The following transcript uses a placeholder path for that locally prepared wheel. It is not a package you should look up or install from a public index. To repeat this exact experiment, prepare and inspect an equivalent local wheel first. Keep the test cache and tool directories separate from your normal tool installation.
uv tool run --offline --no-python-downloads \
--from /path/to/desk_demo_dist-1.0-py3-none-any.whl \
desk-demo-dist
The first attempt exited with code 1. It reported that the distribution did not provide an executable named desk-demo-dist and listed desk-demo. The package had been installed into the test environment, but our function had not run. That distinction matters: “installed” is an intermediate event, not proof that the requested application started.
uv tool run --offline --no-python-downloads \
--from /path/to/desk_demo_dist-1.0-py3-none-any.whl \
desk-demo
The second attempt kept the same wheel and changed only the requested executable. It exited with code 0 and printed DESK_DEMO_OK: local distribution and command names differ. This tests the name mapping without relying on an external package or a working network connection. It does not test every uv version, Windows command wrappers, or the behavior of the reader’s actual application.
Verify the correction at the next boundary
After choosing the verified executable, check that the intended application starts. For a real tool, use an appropriate version or help invocation documented by its publisher before handing it important inputs. Read the output, the exit status and any new error together. A program that starts and then rejects an input has passed the executable lookup boundary but has not completed the user’s task.
Keep a short before-and-after record: exact distribution source, requested executable, uv version, exit code, and the first relevant output. Change one element at a time. In our test the source wheel and interpreter stayed fixed, so the different result could be attributed to the executable name. Changing the Python version, package version and command name together would make that conclusion much weaker.
Do not turn an isolated-tool problem into a project rewrite
Tool execution and project execution have different environment boundaries. If the application needs your project’s installed code, verify that requirement before switching interfaces. The original reader also discussed project execution, but that does not make changing a project’s dependencies necessary to fix a distribution/command mismatch.
For separate environment problems, see the script-versus-module metadata experiment, the project Python selection check, or the sync removal decision. Those guides concern different outcomes. Repeating an install or deleting a lockfile would add changes without explaining the missing executable in this example.
When the names still do not line up
If the package’s current documentation and uv’s executable list disagree, stop guessing. Check that the distribution, version and source are the ones you intended. Preserve the message and ask the publisher with a minimal command and version record. Avoid posting credentials, private index addresses or confidential filenames in a public issue.
Method: a historical reader question identifies the problem; current official documentation supplies the naming syntax; an inspected local wheel supplies the observed exit codes. The local test is evidence for this narrow mapping behavior, not a test of toolong or a guarantee that a reader’s downstream command will succeed.