{"record":{"id":"65160adf0ff8d733","repo":"golang/go","slug":"destination-is-not-a-directory","errorCode":null,"errorMessage":"destination is not a directory","messagePattern":"destination is not a directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/internal/script/cmds.go","lineNumber":292,"sourceCode":"func Cp() Cmd {\n\treturn Command(\n\t\tCmdUsage{\n\t\t\tSummary: \"copy files to a target file or directory\",\n\t\t\tArgs:    \"src... dst\",\n\t\t\tDetail: []string{\n\t\t\t\t\"src can include 'stdout' or 'stderr' to copy from the script's stdout or stderr buffer.\",\n\t\t\t},\n\t\t},\n\t\tfunc(s *State, args ...string) (WaitFunc, error) {\n\t\t\tif len(args) < 2 {\n\t\t\t\treturn nil, ErrUsage\n\t\t\t}\n\n\t\t\tdst := s.Path(args[len(args)-1])\n\t\t\tinfo, err := os.Stat(dst)\n\t\t\tdstDir := err == nil && info.IsDir()\n\t\t\tif len(args) > 2 && !dstDir {\n\t\t\t\treturn nil, &fs.PathError{Op: \"cp\", Path: dst, Err: errors.New(\"destination is not a directory\")}\n\t\t\t}\n\n\t\t\tfor _, arg := range args[:len(args)-1] {\n\t\t\t\tvar (\n\t\t\t\t\tsrc  string\n\t\t\t\t\tdata []byte\n\t\t\t\t\tmode fs.FileMode\n\t\t\t\t)\n\t\t\t\tswitch arg {\n\t\t\t\tcase \"stdout\":\n\t\t\t\t\tsrc = arg\n\t\t\t\t\tdata = []byte(s.Stdout())\n\t\t\t\t\tmode = 0666\n\t\t\t\tcase \"stderr\":\n\t\t\t\t\tsrc = arg\n\t\t\t\t\tdata = []byte(s.Stderr())\n\t\t\t\t\tmode = 0666\n\t\t\t\tdefault:","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/internal/script/cmds.go#L274-L310","documentation":"Returned by the script Cp command when more than two arguments are supplied (multiple sources to one destination) but the destination path does not resolve to an existing directory. Cp requires that a multi-source invocation copy into a directory; otherwise the copy is ambiguous. The error is wrapped as an fs.PathError with Op \"cp\" and the destination Path so it carries the offending path.","triggerScenarios":"Writing a script-test line like `cp a.txt b.txt dir/` where 'dir/' does not exist or is a regular file. Cp is invoked with len(args) > 2, os.Stat(dst) either errors or returns a non-directory, so dstDir is false and the PathError is returned before any source is read.","commonSituations":"Script-test author forgets to `mkdir` the target directory first, or typos the destination name, or points at a file that should have been a directory. Also when copying stdout/stderr plus a file into a non-existent dir: `cp stdout a.txt out/`.","solutions":["Precede the cp with `mkdir out/` (or the Mkdir command) so the destination directory exists.","Reduce to a two-argument cp if you intend file-to-file copy: `cp a.txt b.txt`.","Check the destination path spelling in the script line.","If the directory exists, verify the script's working dir (script.WorkDir / cd) matches where you expect it."],"exampleFix":"// before (script.txt)\ncp a.txt b.txt out/\n# -> cp out/: destination is not a directory\n\n// after\nmkdir out/\ncp a.txt b.txt out/","handlingStrategy":"validation","validationCode":"// Before cp, ensure the multi-source destination is an existing dir.\nfunc ensureCpDest(args ...string) error {\n    if len(args) <= 2 { return nil }\n    info, err := os.Stat(args[len(args)-1])\n    if err != nil || !info.IsDir() {\n        return fmt.Errorf(\"%s is not a directory\", args[len(args)-1])\n    }\n    return nil\n}","typeGuard":"func isDestNotDir(err error) bool {\n    var pe *fs.PathError\n    return errors.As(err, &pe) && pe.Op == \"cp\" && pe.Err != nil &&\n        strings.Contains(pe.Err.Error(), \"destination is not a directory\")\n}","tryCatchPattern":"// In a script test, mkdir first; the engine surfaces the PathError directly.\nmkdir out/\ncp a.txt b.txt out/","preventionTips":["Always mkdir the destination directory before a multi-source cp in script tests.","Use a two-argument cp for file-to-file copies.","Keep script working directories explicit (cd) so dest paths resolve as expected."],"tags":["script","test-framework","cp","filesystem","path-error"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}