Path mappings¶
Path mappings translate between the paths the debuggee knows and the paths on your machine. You need them whenever the code does not run where it is edited.
When you need them¶
- PHP running in a Docker container, where the project is mounted at
/app. - Any adapter attached to a process on another machine.
- Code built in a container and debugged on the host.
You do not need them when the program runs locally from the same paths you edit, which is the normal case for Rust, Go and Python.
The PHP case¶
[profiles.docker]
adapter = "php"
program = "."
[profiles.docker.launch_arguments]
sessionMode = "server"
port = 9003
pathMappings = { "/app" = "${root}" }
Read it as container path = host path. Xdebug reports /app/src/index.php;
Bugsaur turns that into <root>/src/index.php, which your editor can open.
The translation runs both ways: breakpoints you set on host paths are sent to Xdebug as container paths, which is why breakpoints without a mapping never bind.
Several mounts¶
Order does not matter; the longest matching prefix is used.
Getting the mapping right¶
The single most common mistake is guessing the container path. Ask the container rather than assuming:
Compare that with the volumes: entry in your docker-compose.yml:
The left side of the volume is the host path, the right side is the container
path, and pathMappings mirrors that pairing.
Symptoms of a wrong mapping¶
| Symptom | What it means |
|---|---|
| The debugger stops but shows no source | the reported path does not exist locally |
Breakpoints stay pending and never bind |
host paths never match container paths |
| The wrong file opens at the right line number | the prefix maps to the wrong directory |
| Everything works except one directory | a second mount has no mapping |
Full diagnosis: Troubleshooting → Source not found.
For other adapters¶
pathMappings is a key the PHP adapter reads directly. Other adapters have
their own equivalents, and those are passed through launch_arguments
unchanged — for example CodeLLDB's source map:
[profiles.remote]
adapter = "codelldb"
program = "build/app"
[profiles.remote.launch_arguments]
sourceMap = { "/build" = "${root}" }
What the key is called and what it accepts is the adapter's business; Bugsaur passes the body through. See Debug adapters.