Skip to content

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

pathMappings = { "/app" = "${root}", "/vendor-src" = "${root}/vendor" }

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:

docker compose exec php pwd
docker compose exec php ls /app

Compare that with the volumes: entry in your docker-compose.yml:

services:
  php:
    volumes:
      - .:/app          # host . -> container /app

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.