{"record":{"id":"66610c77f4d5a6a3","repo":"ipfs/kubo","slug":"s-mfs-destination-is-a-file-only-one-entry-can","errorCode":null,"errorMessage":"%s: MFS destination is a file: only one entry can be copied to %q","messagePattern":"(.+?): MFS destination is a file: only one entry can be copied to %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/commands/add.go","lineNumber":609,"sourceCode":"\t\t\t\t\tif dstAsDir {\n\t\t\t\t\t\tmfsNode, err := mfs.Lookup(ipfsNode.FilesRoot, toFilesDst)\n\t\t\t\t\t\t// confirm dst exists\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrCh <- fmt.Errorf(\"%s: MFS destination directory %q does not exist: %w\", toFilesOptionName, toFilesDst, err)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// confirm dst is a dir\n\t\t\t\t\t\tif mfsNode.Type() != mfs.TDir {\n\t\t\t\t\t\t\terrCh <- fmt.Errorf(\"%s: MFS destination %q is not a directory\", toFilesOptionName, toFilesDst)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// if MFS destination is a dir, append filename to the dir path\n\t\t\t\t\t\ttoFilesDst += gopath.Base(addit.Name())\n\t\t\t\t\t}\n\n\t\t\t\t\t// error if we try to overwrite a preexisting file destination\n\t\t\t\t\tif fileAddedToMFS && !dstAsDir {\n\t\t\t\t\t\terrCh <- fmt.Errorf(\"%s: MFS destination is a file: only one entry can be copied to %q\", toFilesOptionName, toFilesDst)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\t_, err = mfs.Lookup(ipfsNode.FilesRoot, gopath.Dir(toFilesDst))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrCh <- fmt.Errorf(\"%s: MFS destination parent %q %q does not exist: %w\", toFilesOptionName, toFilesDst, gopath.Dir(toFilesDst), err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tvar nodeAdded ipld.Node\n\t\t\t\t\tnodeAdded, err = api.Dag().Get(req.Context, pathAdded.RootCid())\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrCh <- err\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\terr = mfs.PutNode(ipfsNode.FilesRoot, toFilesDst, nodeAdded)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrCh <- fmt.Errorf(\"%s: cannot put node in path %q: %w\", toFilesOptionName, toFilesDst, err)","sourceCodeStart":591,"sourceCodeEnd":627,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/add.go#L591-L627","documentation":"When adding multiple files with --to-files pointing at a file destination (no trailing slash), only one entry may be linked into MFS. The command tracks whether a file has already been placed (fileAddedToMFS); a second entry targeting the same file path would overwrite it, so it aborts. This protects against silently replacing the first MFS link with the second.","triggerScenarios":"Run `ipfs add --to-files /out.bin fileA fileB` (or `ipfs add -r --to-files /out.bin dir/`): the first entry links to /out.bin, the second entry hits fileAddedToMFS && !dstAsDir and errors with 'MFS destination is a file: only one entry can be copied to /out.bin'.","commonSituations":"Users add a directory recursively while --to-files points at a single file; users pass multiple file arguments expecting concatenation into one MFS path; batch scripts that reuse one --to-files target for several adds in one invocation.","solutions":["Use a directory destination with a trailing slash, e.g. --to-files /dir/, so each entry is placed under its own name","Split into separate `ipfs add --to-files` invocations, one per destination file","Check argument count / recursive flag before running when --to-files targets a file"],"exampleFix":"// before\nipfs add -r --to-files /out.bin ./mydir\n// after\nipfs add -r --to-files /out/ ./mydir   # trailing slash: per-entry names under /out/","handlingStrategy":"validation","validationCode":"// ensure a file-destination add receives exactly one entry\ncount=$(find src -type f | wc -l)\nif [ \"$count\" -gt 1 ]; then dst=\"/out/\"; else dst=\"/out.bin\"; fi\nipfs add --to-files \"$dst\" $(find src -type f)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer directory destinations (trailing slash) when adding more than one entry","Never combine -r/--recursive with a single-file --to-files target","Loop over files with one `ipfs add --to-files` call per destination instead of batching"],"tags":["cli","mfs","to-files","batch-add"],"backgroundTag":"mfs-destination-overwrite-conflict","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}