docker/compose · error
cannot specify DEPRECATED "--workdir" and "--project-directo
Error message
cannot specify DEPRECATED "--workdir" and "--project-directory". Please use only "--project-directory" instead
What it means
The hidden root flag --workdir is deprecated in favor of --project-directory, and the two cannot be combined. During option normalization in cmd/compose/compose.go, if opts.WorkDir is non-empty while opts.ProjectDir is also set, the command fails immediately. --workdir alone still works: its value is copied into ProjectDir and a red deprecation notice is printed to stderr.
Source
Thrown at cmd/compose/compose.go:520
switch ansi {
case "never":
display.Mode = display.ModePlain
case "always":
display.Mode = display.ModeTTY
}
detached, _ := cmd.Flags().GetBool("detach")
ep, err := selectEventProcessor(dockerCli, opts.Progress, ansi, detached)
if err != nil {
return err
}
backendOptions.Add(compose.WithEventProcessor(ep))
// (4) options validation / normalization
if opts.WorkDir != "" {
if opts.ProjectDir != "" {
return errors.New(`cannot specify DEPRECATED "--workdir" and "--project-directory". Please use only "--project-directory" instead`)
}
opts.ProjectDir = opts.WorkDir
fmt.Fprint(os.Stderr, aec.Apply("option '--workdir' is DEPRECATED at root level! Please use '--project-directory' instead.\n", aec.RedF))
}
for i, file := range opts.EnvFiles {
file = composepaths.ExpandUser(file)
if !filepath.IsAbs(file) {
file, err := filepath.Abs(file)
if err != nil {
return err
}
opts.EnvFiles[i] = file
} else {
opts.EnvFiles[i] = file
}
}
composeCmd := cmdView on GitHub (pinned to ddc4b044b6)
Solutions
- Replace --workdir <path> with --project-directory <path> and keep a single occurrence of the flag.
- Check shell aliases and CI templates for leftover --workdir usage and update them.
- Alternatively use the COMPOSE_PROJECT_DIR environment variable if supported by your workflow, but prefer the explicit flag.
Example fix
# before docker compose --workdir /srv/app --project-directory /srv/app up # after docker compose --project-directory /srv/app up
Defensive patterns
Strategy: validation
Validate before calling
# reject command lines mixing both flags if printf '%s\n' "$@" | grep -q -- '--workdir' && printf '%s\n' "$@" | grep -q -- '--project-directory'; then echo "--workdir is deprecated; keep only --project-directory" >&2 exit 1 fi
Prevention
- Migrate all v1-era scripts from --workdir to --project-directory once, centrally.
- Lint compose invocations in CI (grep for --workdir) to catch regressions.
When it happens
Trigger: Any docker compose invocation that passes both flags, e.g. `docker compose --workdir /app --project-directory /other up`, or a wrapper/alias that always injects --project-directory while the user adds --workdir.
Common situations: Scripts or Makefiles dating from Compose v1 (which used --workdir) that were partially migrated to v2 syntax; tools like IDE run configurations that append --project-directory automatically while the user adds --workdir manually.
Related errors
- cannot specify DEPRECATED "--no-ansi" and "--ansi". Please u
- --index requires one service to be selected
- cannot combine --attach and --attach-dependencies
- can't use --progress plain while ANSI support is forced
- unsupported --progress value %q
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/8f0038c9bc971899.
Report an issue: GitHub.