{"record":{"id":"d789d9fc2100c3f7","repo":"ipfs/kubo","slug":"not-a-file-s","errorCode":null,"errorMessage":"not a file: %s","messagePattern":"not a file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/commands/files.go","lineNumber":662,"sourceCode":"\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\n\tpdir, ok := parent.(*mfs.Directory)\n\tif !ok {\n\t\treturn fmt.Errorf(\"not a directory: %s\", dir)\n\t}\n\n\t// Attempt to unlink if child is a file, ignore error since\n\t// we are only concerned with unlinking an existing file.\n\tchild, err := pdir.Child(name)\n\tif err != nil {\n\t\treturn nil // no child file, nothing to unlink\n\t}\n\n\tif child.Type() != mfs.TFile {\n\t\treturn fmt.Errorf(\"not a file: %s\", path)\n\t}\n\n\treturn pdir.Unlink(name)\n}\n\ntype filesLsOutput struct {\n\tEntries []mfs.NodeListing\n}\n\nconst (\n\tlongOptionName     = \"long\"\n\tdontSortOptionName = \"U\"\n)\n\nvar filesLsCmd = &cmds.Command{\n\tHelptext: cmds.HelpText{\n\t\tTagline: \"List directories in the local mutable namespace.\",\n\t\tShortDescription: `","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/files.go#L644-L680","documentation":"unlinkNodeIfExists fetched the child at the destination path and asserts it is an MFS file (mfs.TFile) before unlinking. If the existing child is another type (typically a directory), it returns \"not a file: <path>\" — cp --force will not silently delete directories.","triggerScenarios":"Running `ipfs files cp --force <src> <dst>` where dst exists and is a directory (or symlink/other non-file MFS node), so the pre-unlink safety check refuses to remove it.","commonSituations":"Overwriting an existing MFS directory with a file using --force; scripts assuming --force acts like `rm -r`; dst previously created by `ipfs files mkdir`.","solutions":["Remove the directory explicitly first: `ipfs files rm -r <dst>`, then run `ipfs files cp` without --force","Choose a different dst name that does not collide with the existing directory","Verify dst type with `ipfs files stat <dst>` before using --force","If the directory should be preserved, copy into it: `ipfs files cp <src> <dst>/<name>`"],"exampleFix":"// before\nipfs files cp --force /ipfs/Qm... /my-dir\n// error: not a file: /my-dir\n\n// after\nipfs files rm -r /my-dir\nipfs files cp /ipfs/Qm... /my-dir","handlingStrategy":"validation","validationCode":"// refuse --force overwrite of directories before calling cp\nif t := pathType(dst); t == \"directory\" {\n    run(\"ipfs\", \"files\", \"rm\", \"-r\", dst)\n}","typeGuard":"func isMFSFile(p string) bool {\n    out, err := run(\"ipfs\", \"files\", \"stat\", p)\n    return err == nil && strings.Contains(out, \"file\")\n}","tryCatchPattern":"if err := ipfsFilesCpForce(src, dst); err != nil {\n    if strings.Contains(err.Error(), \"not a file\") {\n        // dst is a directory: rm -r it first or pick another name\n    }\n}","preventionTips":["`ipfs files stat <dst>` before any --force copy","Treat --force as file-overwrite only, never as rm -r","Copy into directories via `<dst>/<name>` instead of overwriting them"],"tags":["mfs","cli","cp"],"backgroundTag":"not-a-file","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"}