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

  1. Invoke compose the supported way: `docker compose ...` so the plugin root is named 'compose'
  2. If you renamed the root in a fork, revert the root command's Use to keep 'compose'
  3. 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

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


AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15). Data as JSON: /api/errors/ac3b27c59a2896d4. Report an issue: GitHub.