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
- Fix the source argument: verify the variable is set and non-empty before invoking cp (e.g. : "${SRC:?source path required}").
- If copying from stdin, use the literal '-' as the source argument.
- 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
- Use ${VAR:?message} guards for every interpolated cp argument.
- Use the literal '-' when streaming from stdin.
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
- destination can not be empty
- invalid filter '${filter}'
- --index requires one service to be selected
- arguments to --filter should be in form KEY=VAL
- cannot combine --attach and --attach-dependencies
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/180b39e2a43bfcb8.
Report an issue: GitHub.