{"record":{"id":"e3c271482129ffdb","repo":"ipfs/kubo","slug":"s-w","errorCode":null,"errorMessage":"%s: %w","messagePattern":"%s: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/commands/add.go","lineNumber":586,"sourceCode":"\t\t\t\t// creating MFS pointers when optional --to-files is set\n\t\t\t\tif toFilesSet {\n\t\t\t\t\t// The link creates new MFS directory nodes that are not\n\t\t\t\t\t// pinned, so guard it against a concurrent GC. For an\n\t\t\t\t\t// unpinned add the lock is already held above.\n\t\t\t\t\tif dopin {\n\t\t\t\t\t\tdefer ipfsNode.Blockstore.PinLock(req.Context).Unlock(req.Context)\n\t\t\t\t\t}\n\t\t\t\t\tif addit.Name() == \"\" {\n\t\t\t\t\t\terrCh <- fmt.Errorf(\"%s: cannot add unnamed files to MFS\", toFilesOptionName)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tif toFilesStr == \"\" {\n\t\t\t\t\t\ttoFilesStr = \"/\"\n\t\t\t\t\t}\n\t\t\t\t\ttoFilesDst, err := checkPath(toFilesStr)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrCh <- fmt.Errorf(\"%s: %w\", toFilesOptionName, err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tdstAsDir := toFilesDst[len(toFilesDst)-1] == '/'\n\n\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())","sourceCodeStart":568,"sourceCodeEnd":604,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/add.go#L568-L604","documentation":"Before linking into MFS, the `--to-files` value is normalized by checkPath, which rejects strings that are not valid MFS paths (e.g. missing the leading '/'). The underlying checkPath error is wrapped with the --to-files option name for context.","triggerScenarios":"`ipfs add --to-files=relative/path file` (no leading slash); a malformed or invalid destination string; programmatic RPC calls building ToFiles without normalizing the path.","commonSituations":"Scripts assembling destinations from variables and losing the leading slash; users confusing MFS paths with local filesystem paths.","solutions":["Use an absolute MFS path starting with '/', e.g. --to-files=/data/file.bin","Validate/normalize the destination before invoking add (ensure a single leading slash)","Pass '/' explicitly when defaulting to the MFS root"],"exampleFix":"// before\nipfs add --to-files=docs/report.md report.md\n// after\nipfs add --to-files=/docs/report.md report.md","handlingStrategy":"validation","validationCode":"func normalizeMFSDst(p string) (string, error) {\n  if !strings.HasPrefix(p, \"/\") {\n    return \"\", fmt.Errorf(\"MFS path must be absolute: %q\", p)\n  }\n  return path.Clean(p), nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always build --to-files destinations with a leading '/'","Run paths through path.Clean and require absoluteness in shared helpers"],"tags":["cli","mfs","path-validation","to-files"],"backgroundTag":"invalid-mfs-path","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"}