Running uv scripts in debug mode
Hi all!
I am trying to see if we can start using uv to manage our codebases. Everything seems to work great, and managing dependencies is a lot easier this way! However, I can't figure out how to run a program through uv in debug mode in either VS Code or PyCharm. (e.g., uv run src/main.py) Does anyone have experience with running uv scripts in debug mode and can you point me in the right direction? :)
Thank you!
Related to https://github.com/astral-sh/uv/issues/7803
We don't have a great recommendation here yet.
I configured an alias (alias python="uv run python") and am able to debug apps/scripts without any modification to my VS Code config (and without forcing other devs to use uv if they aren't ready to migrate yet). I do feel like this is more of a workaround and has its pros/cons, but I'm happy with using this as a working solution to remove the barrier to utilizing uv.
That's a great workaround @emilyemorehouse! I will definitely be using this myself as well. However, before I can convince the rest of my team that we should start using uv everywhere, it is important to have a less 'hacky' way to debug uv programs.
@zanieb, I fully understand this is not at the top of the priority list of uv right now, but I do think it is important to have some sort of solution for this when uv goes more mainstream :)
I agree with @RubenVanEldik : if astral doesn't support common development scenarios (such as debug using vscode), all the other efforts will be meaningless.
another way to see it: now vscode offers support for pip (pipx, ...) and conda (micromamba, ...) environments, so the day I see UV in that list, then I will talk about UV to other developers. I hope that day comes soon
I understand the desire, but it seems like this is sort of something for the VSCode team to tackle. I don't understand the nuances of the debugger setup and if alias python="uv run python" works then it seems like there's not really a technical limitation just a weird constraint on how the Python interpreter is invoked?
I understand the desire, but it seems like this is sort of something for the VSCode team to tackle. I don't understand the nuances of the debugger setup and if
alias python="uv run python"works then it seems like there's not really a technical limitation just a weird constraint on how the Python interpreter is invoked?
I second this!
From what I can see, UV obeys the ancient PEP0405 so any issues with VSCode or PyCharm selecting the correct interpreter stem from the IDE, not UV.
FWIW I also had this issue initially and the alias python="uv run python" hack worked, but was actually no longer needed after restarting VSCode... Perhaps even just restarting the extension host would suffice.
@franperezlopez UV abides by PEP0405. So the UV virtual environment is literally the same as choosing the Venv from the dropdown in the image you shared... it's nothing special and you should just be able to select the correct interpreter for the project as I have done (below).
UV will create a new virtual environment on uv sync or you can create one manually with uv venv. The resulting venv should appear as an option when selecting an interpreter for the project. I think you could even just choose the Venv option you showed, and UV will automatically sync packages to that venv.
I did have issues initially with VS Codes debugger using the right interpreter - but restarting VS Code fixed this... perhaps even just restarting the extension host would work. This strongly plus UVs PEP compliance indicates to me the issue lies with VS Code and not UV.
You can run your FastAPI application using the following configuration in launch.json:
{
"name": "api",
"type": "debugpy",
"request": "launch",
"module": "app",
"console": "internalConsole",
"justMyCode": true
}
In this configuration, "app" refers to the Python module that contains the file main.py. main.py Create a file named main.py with the following content:
import uvicorn
if __name__ == '__main__':
uvicorn.run("app.server:create_app", host="127.0.0.1", port=8000, reload=True, factory=True)
Here, server.py is the entry point of the application, and create_app is the application factory function. Using a factory pattern is recommended for better flexibility. server.py In your server.py, define the application factory as follows:
from fastapi import FastAPI
def create_app() -> FastAPI:
app = FastAPI()
return app
Running the Application With this setup, you can run your FastAPI application in debug mode directly from Visual Studio Code. Simply select the configuration named "api" from the debug panel and start debugging. This configuration allows you to take advantage of debugging features such as breakpoints and variable inspection while developing your FastAPI application. Final Notes Ensure Dependencies: Make sure you have all necessary dependencies installed, including FastAPI and Uvicorn. Directory Structure: Ensure that your directory structure supports this setup, with main.py located in the correct module path.
├── app/
│ ├── __init__.py
│ ├── __main__.py
│ └── server.py
I think the more vs-code way of doing this until support for uv is added is:
-
Select the interpreter (
uv run which pythonif you are not sure) with the command palette like here -
Add the launch config for a script at
${workspaceFolder}/tests/test_script.pytolaunch.json
{
"name": "my_test_script",
"request": "launch",
"cwd": "${workspaceFolder}/tests",
"type":"debugpy",
"program": "src/tests/test_script.py",
"console": "integratedConsole",
"args": [
"arg1": "value1"
]
},
FWIW I also had this issue initially and the
alias python="uv run python"hack worked, but was actually no longer needed after restarting VSCode... Perhaps even just restarting the extension host would suffice.
This is exactly what happened to me. I've also ditched the alias and simply selecting the right interpreter in VS Code (from the venv that I create with uv and auto-activate with direnv) is working seamlessly.
I also agree that this isn't a uv issue – it's up to each debugger/editor to support uv-specific things that don't fit into this box.
I bumped into this while trying to debug pytest execution within a uv environment. If you need to do the same, this launch.json file should work for you:
{
"version": "0.2.0",
"configurations": [
{
"justMyCode": false,
"name": "uv+pytest",
"type": "debugpy",
"request": "launch",
"program": ".venv/bin/pytest", #path to your venv's pytest bin
"python": "${command:python.interpreterPath}", #assuming the correct interpreter is already selected in VSC
"console": "integratedTerminal",
"args": "path/to/test.py" #path to the test you want to run; can be a list; these are the args passed to pytest
}
]
}
For VS code, I added uv sync as a preLaunchtask to make sure my environment is up-to-date.
launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: Current File",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"preLaunchTask": "uv_sync"
}
]
}
tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "uv_sync",
"type": "shell",
"command": "uv sync"
}
]
}
These workarounds do not work with uv run script.py where the dependencies are included using uv's script dependencies, do they?
Where scripting is often where it is useful to try out things and debug. Any suggestions on how to run that from VScode easily in debug mode?
/// script
# dependencies = [
# "pandasgui",
# "pandas",
# "psycopg2",****
@hoegge seems like you can use uv sync --script <SCRIPT> at least on uv 0.7.21 (Homebrew 2025-07-14). This command also helpfully prints the directory where the virtual environment lives if you want to manually explore things.
You can also get the path with uv sync --script example.py --dry-run --output-format json | jq -r '.sync.environment.path'
@hoegge FYI, thanks to @say4n and @zanieb indications, I could run from VSCode Debugger my Python script with uv script dependencies by:
- Selecting as interpreter the
pythonbin inbin/pythonin theuvenvironment directory printed by theuv sync --script ...command. - Setting the
launch.jsonaccording to @adithyakirank indications to run my Python script. (Note that it is"console": "internalConsole"and not"console": "integratedConsole"as stated in its comment)
Hope it may be useful to anyone around here.
@hoegge FYI, thanks to @say4n and @zanieb indications, I could run from VSCode Debugger my Python script with
uvscript dependencies by:
- Selecting as interpreter the
pythonbin inbin/pythonin theuvenvironment directory printed by theuv sync --script ...command.- Setting the
launch.jsonaccording to @adithyakirank indications to run my Python script. (Note that it is"console": "internalConsole"and not"console": "integratedConsole"as stated in its comment)Hope it may be useful to anyone around here.
My bad, the console options are indeed one of the following values:
console - what kind of console to use, for example, internalConsole, integratedTerminal, or externalTerminal
These workarounds do not work with uv run script.py where the dependencies are included using uv's script dependencies, do they?
If you are also fine with debugging with pdb, you can simply add a breakpoint() statement in your Python script and run uv sync --script <SCRIPT> as usual. This will stop the program at the breakpoint and leave you with the interactive pdb session.
Yet another way that has worked well for me.
It uses the python and pythonArgs values to substitute in uv run python instead of the default interpreter so it should mean that it's equivalent to running uv run python ${file}
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug with uv",
"type": "debugpy",
"request": "launch",
"python": "uv",
"pythonArgs": [
"run",
"python"
],
"program": "${file}"
}
]
}
Thanks!!! @emilyemorehouse 🧠
Yet another way that has worked well for me.
It uses the
pythonandpythonArgsvalues to substitute inuv run pythoninstead of the default interpreter so it should mean that it's equivalent to runninguv run python ${file}{ "version": "0.2.0", "configurations": [ { "name": "Debug with uv", "type": "debugpy", "request": "launch", "python": "uv", "pythonArgs": [ "run", "python" ], "program": "${file}" } ] }
Hello, I get this error message when trying to use your proposed launch.json.
Could you give me advice if I need to change something? Or add something to my environment? Thanks!
Yet another way that has worked well for me. It uses the
pythonandpythonArgsvalues to substitute inuv run pythoninstead of the default interpreter so it should mean that it's equivalent to runninguv run python ${file}{ "version": "0.2.0", "configurations": [ { "name": "Debug with uv", "type": "debugpy", "request": "launch", "python": "uv", "pythonArgs": [ "run", "python" ], "program": "${file}" } ] }Hello, I get this error message when trying to use your proposed
launch.json.Could you give me advice if I need to change something? Or add something to my environment? Thanks!
Are you able to provide the output of the Python Debug Console terminal that spawns when starting the debug task? Also can include Output > Python and Output > Python Debugger.
Potentially something to do with things not being found but when I intentionally change any of the values in there to pretend they can't be found, I get a pretty clear error message.
Thank you @fionn-r for your reply.
Using the launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug with uv",
"type": "debugpy",
"request": "launch",
"python": "uv",
"pythonArgs": [
"run",
"python"
],
"program": "${file}"
}
]
}
The outputs I got when trying to debug are:
Python Debugger
2025-10-07 10:47:07.840 [info] Resolving launch configuration with substituted variables
Python Locator
2025-10-07 10:48:35.022 [info] Resolved Python Environment C:\Users\xyz\.venv\Scripts\python.exe
2025-10-07 10:48:35.113 [error] Failed to execute Python to resolve info "\"c:\\Users\\xyz\\.venv\\Scripts\\python.exe\"": El nombre de archivo, el nombre de directorio o la sintaxis de la etiqueta del volumen no son correctos. (os error 123)
2025-10-07 10:48:35.113 [warning] Unknown Python Env "\"c:\\Users\\xyz\\.venv\\Scripts\\python.exe\""
2025-10-07 10:48:35.113 [error] Failed to resolve env "\"c:\\Users\\xyz\\.venv\\Scripts\\python.exe\""
But the `python.exe´ it is at that location. I triple checked.
The error is:
And the debug does not start.
I am using uv:
uv 0.8.23 (00d3aa378 2025-10-04)
When VScode starts, the Python locator find python.exe without any error:
2025-10-07 10:53:03.475 [info] Resolved Python Environment C:\Users\xyz\.venv\Scripts\python.exe
Any ideas what could be wrong?
The only thing I can think of is that python path looks a bit weird to me and I'm thinking it's potentially failing launching the debugpy instance before even launching your program.
I would double check your python interpreter path, maybe just reselect it (ctrl+shift+p >Python Select Interpreter and choose the venv interpreter).
Does just running a regular debug instance work? Something like:
{
"name": "Debug with python",
"type": "debugpy",
"request": "launch",
"program": "${file}"
}
If that works fine then sorry I'm a bit stumped.
@fionn-r , I think I have found the issue. The issue is the folders with "spaces". My file path is like:
C:\Users\me\This folder\This app\src\python.exe
I moved everything to
C:\Users\me\src\python.exe
And now, works with:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug with uv",
"type": "debugpy",
"request": "launch",
"python": "uv",
"pythonArgs": [
"run",
"python"
],
"program": "${file}"
}
]
}
And with the default configuration.
It's very strange how bad VSCode is managing the spaces.
These workarounds do not work with uv run script.py where the dependencies are included using uv's script dependencies, do they? Where scripting is often where it is useful to try out things and debug. Any suggestions on how to run that from VScode easily in debug mode?
@hoegge I believe I found a way to run the VSCode debugger on scripts with inline dependencies 🙂.
{
"version": "0.2.0",
"configurations": [
{
"name": "UV Python Script",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"python": "uv",
"pythonArgs": [
"run", "--with-requirements", "${file}", "python"
]
}
]
}
This uses the uv run option --with-requirements to install the inline dependencies into an ephemeral environment and then runs the corresponding script.
Notes: First, I tried the config from @fionn-r, which runs Python but without installing the dependencies from the inline script metadata.
Using "pythonArgs": ["run", "--script"] also does not work because VSCode assumes that "python" is a Python interpreter and passes additional arguments to the command (e.g. -X frozen_modules=off (...)).
@RafaelWO , exciting to see, was just struggling with that same issue with inline deps last night. I'm still finding two issues:
UPDATE: See below, the launch.json config was slightly out of whack; also need to have a more recent version of uv to handle (uv 0.9.0 works)
I couldn't quite get your chunk to run successfully on an example file:
(example-uv-made-venv) PS C:\Users\username\Documents\projects\example-project> C:; cd 'C:\Users\username\Documents\projects\example-project'; & 'c:\Users\username\Documents\projects\example-project\.venv\Scripts\python.exe' 'c:\Users\username\.vscode\extensions\ms-python.debugpy-2025.10.0-win32-x64\bundled\libs\debugpy\launcher' '49986' '--' 'C:\Users\username\Documents\projects\example-project\analyses\pep723-example.py'
error: File not found: `python`
this was the launch.json chunk (just added cwd item):
{
"name": "uv debug test",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"python": "uv",
"cwd": "${workspaceFolder}",
"pythonArgs": ["run", "--with-requirements", "python", "${file}"]
}
This is a minimal python file example; the debug launch was triggered with this file active in vscode.
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "requests>=2.31.0"
# ]
# ///
"""
Minimal PEP 723 example script with cli args
Examples:
uv run analyses/pep723-example.py
uv run analyses/pep723-example.py --message "Custom message"
"""
import argparse
import requests # not used, just to test that inline deps work
def main():
"""Main function to parse arguments and print the message."""
parser = argparse.ArgumentParser(
description="Minimal PEP 723 example with optional argument"
)
parser.add_argument(
"--message", default="Hello, World!", help="Message to print to console"
)
args = parser.parse_args()
print(f"You provided: {args.message}")
if __name__ == "__main__":
main()
I'm curious if this example works on your end, or if there's just some other misconfiguration happening on my end or i'm too far behind on the version now (windows 10, uv 0.7.22, current vscode version). More broadly, i'm also having a bit of trouble getting arguments that are required at the command line to work with some of these uv-oriented launch configs. Can get debugger going fine in other repos that don't use uv, but not so much here.
@wtimmerman-fitp You mixed up two of the Python args in your launch.json 😉
- "pythonArgs": ["run", "--with-requirements", "python", "${file}"]
+ "pythonArgs": ["run", "--with-requirements", "${file}", "python"]
The option --with-requirements expects the file you want to run. Hopefully, it works if you swap the last two arguments 🙂
More broadly, i'm also having a bit of trouble getting arguments that are required at the command line to work
To specify arguments to the Python script that are parsed via argparse, you have to set the "args" key in your lauch.json:
{
...
"cwd": "${workspaceFolder}",
"pythonArgs": ["run", "--with-requirements", "${file}", "python"],
"args": ["--message", "Hi from VSCode"]
}
If you manually want to enter args upon starting the debugger, I recommend using "args": "${command:pickArgs}" which opens an input dialog to pass options if you start debugging. You can find more info in the VSCode docs on Python debugging.
Oh goodness, perils of debugging for too long...
In my defense, hah, i had also tried what you put and received this other error previously:
error: Unexpected '"', expected '-c', '-e', '-r' or the start of a requirement at analyses\pep723-example.py:8:1
but, seems like an upgrade from 0.7.22 to a later version (0.9.0 in my case) did the trick.
So, big thanks, @RafaelWO ! And appreciate the insight on the additional args and your response on this item
Thanks a lot @RafaelWO - it seems to work perfectly. Great!
@hoegge I believe I found a way to run the VSCode debugger on scripts with inline dependencies 🙂.
{ "version": "0.2.0", "configurations": [ { "name": "UV Python Script", "type": "debugpy", "request": "launch", "program": "${file}", "python": "uv", "pythonArgs": [ "run", "--with-requirements", "${file}", "python" ] } ] } This uses the
uv runoption--with-requirementsto install the inline dependencies into an ephemeral environment and then runs the corresponding script.Notes: First, I tried the config from @fionn-r, which runs Python but without installing the dependencies from the inline script metadata.
Using
"pythonArgs": ["run", "--script"]also does not work because VSCode assumes that"python"is a Python interpreter and passes additional arguments to the command (e.g.-X frozen_modules=off (...)).
Could you give me advice if I need to change something? Or add something to my environment? Thanks!