docker/compose · error

source can not be empty

Error message

source can not be empty

What it means

docker compose cp requires exactly two non-empty positional arguments (enforced by cli.ExactArgs(2) plus a PreRunE check). The PreRunE in cmd/compose/cp.go validates that args[0] — the source, either SERVICE:SRC_PATH or a local SRC_PATH / '-' for stdin — is not the empty string. An empty first argument passes cobra's arg-count check but fails this guard before any container operation starts.

Source

Thrown at cmd/compose/cp.go:53

	destination string
	index       int
	all         bool
	followLink  bool
	copyUIDGID  bool
}

func copyCommand(p *ProjectOptions, dockerCli command.Cli, backendOptions *BackendOptions) *cobra.Command {
	opts := copyOptions{
		ProjectOptions: p,
	}
	copyCmd := &cobra.Command{
		Use: `cp [OPTIONS] SERVICE:SRC_PATH DEST_PATH|-
	docker compose cp [OPTIONS] SRC_PATH|- SERVICE:DEST_PATH`,
		Short: "Copy files/folders between a service container and the local filesystem",
		Args:  cli.ExactArgs(2),
		PreRunE: Adapt(func(ctx context.Context, args []string) error {
			if args[0] == "" {
				return errors.New("source can not be empty")
			}
			if args[1] == "" {
				return errors.New("destination can not be empty")
			}
			return nil
		}),
		RunE: AdaptCmd(func(ctx context.Context, cmd *cobra.Command, args []string) error {
			opts.source = args[0]
			opts.destination = args[1]
			return runCopy(ctx, dockerCli, backendOptions, opts)
		}),
		ValidArgsFunction: completeServiceNames(dockerCli, p),
	}

	flags := copyCmd.Flags()
	flags.IntVar(&opts.index, "index", 0, "Index of the container if service has multiple replicas")
	flags.BoolVar(&opts.all, "all", false, "Include containers created by the run command")
	flags.BoolVarP(&opts.followLink, "follow-link", "L", false, "Always follow symbol link in SRC_PATH")

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Fix the source argument: verify the variable is set and non-empty before invoking cp (e.g. : "${SRC:?source path required}").
  2. If copying from stdin, use the literal '-' as the source argument.
  3. Double-check the SERVICE:SRC_PATH syntax — the service name and path must both be present on the container side.

Example fix

# before
docker compose cp "$SRC" web:/app
# $SRC unset -> empty-string arg

# after
: "${SRC:?source path required}"
docker compose cp "$SRC" web:/app
Defensive patterns

Strategy: validation

Validate before calling

: "${SRC:?docker compose cp needs a non-empty source}"
docker compose cp "$SRC" "${DEST:?}"

Prevention

When it happens

Trigger: Running `docker compose cp "" dest`, `docker compose cp "" container:/path`, or a script where the source variable expands to empty (e.g. unset $SRC), because shell word-splitting still yields an empty-string argument when quoted.

Common situations: Shell scripts with unset or misnamed source variables; YAML/CI pipelines interpolating an empty value into the cp arguments; copying from stdin ('-') but accidentally quoting an empty variable instead.

Related errors


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