docker/compose · error
error parsing command line, expected %q
Error message
error parsing command line, expected %q
What it means
This is an internal invariant in compose's cobra wiring: the PersistentPreRunE walks up the command tree until it finds the root command named 'compose' (PluginName) to read global flags on it. If the tree has no command with that name (renamed root, standalone miswiring, or a non-standard embedding), the walk hits a parentless command and errors. End users normally never produce it; it signals the binary is being invoked in an unexpected command hierarchy.
Source
Thrown at cmd/compose/compose.go:541
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 := cmd
for composeCmd.Name() != PluginName {
if !composeCmd.HasParent() {
return fmt.Errorf("error parsing command line, expected %q", PluginName)
}
composeCmd = composeCmd.Parent()
}
if v, ok := os.LookupEnv(ComposeParallelLimit); ok && !composeCmd.Flags().Changed("parallel") {
i, err := strconv.Atoi(v)
if err != nil {
return fmt.Errorf("%s must be an integer (found: %q)", ComposeParallelLimit, v)
}
parallel = i
}
if parallel > 0 {
logrus.Debugf("Limiting max concurrency to %d jobs", parallel)
backendOptions.Add(compose.WithMaxConcurrency(parallel))
}
// dry run detection
if dryRun {View on GitHub (pinned to ddc4b044b6)
Solutions
- Invoke compose the supported way: `docker compose ...` so the plugin root is named 'compose'
- If you renamed the root in a fork, revert the root command's Use to keep 'compose'
- Reinstall/align the compose plugin version with your docker CLI (`docker compose version`)
Example fix
// before (fork)
rootCmd := &cobra.Command{Use: "mytool"}
// after
rootCmd := &cobra.Command{Use: compose.PluginName} Defensive patterns
Strategy: try-catch
Validate before calling
# verify the expected command hierarchy before scripting
docker compose version >/dev/null 2>&1 || { echo 'compose plugin misinstalled'; exit 1; } Try / catch
# fork maintainers: assert the root command name during init
if rootCmd.Name() != compose.PluginName {
return fmt.Errorf("root command must be %q, got %q", compose.PluginName, rootCmd.Name())
} Prevention
- Always invoke via `docker compose` so the plugin root is named correctly
- In forks, never rename the root command's Use string
When it happens
Trigger: Running the compose binary with its root command renamed (custom builds), embedding compose's command tree under a different program name, or a plugin invocation where the expected 'compose' root is absent from the chain.
Common situations: Forks/custom builds renaming the root command; invoking the binary via a symlink/wrapper that changes argv[0] semantics combined with odd subcommand routing; version mismatches after partial upgrades of the docker CLI plugin.
Related errors
- cannot specify DEPRECATED "--no-ansi" and "--ansi". Please u
- cannot specify DEPRECATED "--workdir" and "--project-directo
- source can not be empty
- destination can not be empty
- invalid filter '${filter}'
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/ac3b27c59a2896d4.
Report an issue: GitHub.