{"record":{"id":"439268308eaf9bdc","repo":"docker/compose","slug":"destination-s-s-must-be-a-directory","errorCode":null,"errorMessage":"destination \"%s:%s\" must be a directory","messagePattern":"destination \"(.+?):(.+?)\" must be a directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/compose/cp.go","lineNumber":207,"sourceCode":"\t// path exists, in which case the copy may still succeed. If there is any\n\t// type of conflict (e.g., non-directory overwriting an existing directory\n\t// or vice versa) the extraction will fail. If the destination simply did\n\t// not exist, but the parent directory does, the extraction will still\n\t// succeed.\n\tif err == nil {\n\t\tdstInfo.Exists, dstInfo.IsDir = true, dstStat.Mode.IsDir()\n\t}\n\n\tvar (\n\t\tcontent         io.Reader\n\t\tresolvedDstPath string\n\t)\n\n\tif srcPath == \"-\" {\n\t\tcontent = s.stdin()\n\t\tresolvedDstPath = dstInfo.Path\n\t\tif !dstInfo.IsDir {\n\t\t\treturn fmt.Errorf(\"destination \\\"%s:%s\\\" must be a directory\", containerID, dstPath)\n\t\t}\n\t} else {\n\t\t// Prepare source copy info.\n\t\tsrcInfo, err := archive.CopyInfoSourcePath(srcPath, opts.FollowLink)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tsrcArchive, err := archive.TarResource(srcInfo)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer srcArchive.Close() //nolint:errcheck\n\n\t\t// With the stat info about the local source as well as the\n\t\t// destination, we have enough information to know whether we need to\n\t\t// alter the archive that we upload so that when the server extracts\n\t\t// it to the specified directory in the container we get the desired","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/pkg/compose/cp.go#L189-L225","documentation":"Error \"destination \"%s:%s\" must be a directory\" thrown in docker/compose.","triggerScenarios":"When copying multiple source files into a container with 'docker compose cp', the in-container destination must be an existing directory and it is not.","commonSituations":"Multiple sources (or a wildcard-expanded copy) were given with a destination path that is a file or does not exist inside the container.","solutions":["Point the destination at an existing directory inside the container, ending the path with a slash if needed.","Create the directory in the container first with docker compose exec <service> mkdir -p <path>."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}