ipfs/kubo · error

not a file: %s

Error message

not a file: %s

What it means

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.

Source

Thrown at core/commands/files.go:662

			return nil
		}
		return err
	}

	pdir, ok := parent.(*mfs.Directory)
	if !ok {
		return fmt.Errorf("not a directory: %s", dir)
	}

	// Attempt to unlink if child is a file, ignore error since
	// we are only concerned with unlinking an existing file.
	child, err := pdir.Child(name)
	if err != nil {
		return nil // no child file, nothing to unlink
	}

	if child.Type() != mfs.TFile {
		return fmt.Errorf("not a file: %s", path)
	}

	return pdir.Unlink(name)
}

type filesLsOutput struct {
	Entries []mfs.NodeListing
}

const (
	longOptionName     = "long"
	dontSortOptionName = "U"
)

var filesLsCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "List directories in the local mutable namespace.",
		ShortDescription: `

View on GitHub (pinned to 329838acdf)

Solutions

  1. Remove the directory explicitly first: `ipfs files rm -r <dst>`, then run `ipfs files cp` without --force
  2. Choose a different dst name that does not collide with the existing directory
  3. Verify dst type with `ipfs files stat <dst>` before using --force
  4. If the directory should be preserved, copy into it: `ipfs files cp <src> <dst>/<name>`

Example fix

// before
ipfs files cp --force /ipfs/Qm... /my-dir
// error: not a file: /my-dir

// after
ipfs files rm -r /my-dir
ipfs files cp /ipfs/Qm... /my-dir
Defensive patterns

Strategy: validation

Validate before calling

// refuse --force overwrite of directories before calling cp
if t := pathType(dst); t == "directory" {
    run("ipfs", "files", "rm", "-r", dst)
}

Type guard

func isMFSFile(p string) bool {
    out, err := run("ipfs", "files", "stat", p)
    return err == nil && strings.Contains(out, "file")
}

Try / catch

if err := ipfsFilesCpForce(src, dst); err != nil {
    if strings.Contains(err.Error(), "not a file") {
        // dst is a directory: rm -r it first or pick another name
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: Overwriting an existing MFS directory with a file using --force; scripts assuming --force acts like `rm -r`; dst previously created by `ipfs files mkdir`.

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/d789d9fc2100c3f7. Report an issue: GitHub.