{"record":{"id":"76a685c2c784ec45","repo":"AlistGo/alist","slug":"only-write-in-mfs-mode","errorCode":null,"errorMessage":"only write in mfs mode","messagePattern":"only write in mfs mode","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/ipfs_api/driver.go","lineNumber":112,"sourceCode":"\tcase \"mfs\":\n\t\tfileStat, err := d.sh.FilesStat(ctx, rawPath)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tipfsPath = path.Join(\"/ipfs\", fileStat.Hash)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"mode error\")\n\t}\n\tfile, err := d.sh.FilesStat(ctx, ipfsPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &model.Object{ID: file.Hash, Name: path.Base(rawPath), Path: rawPath, Size: int64(file.Size), IsFolder: file.Type == \"directory\"}, nil\n}\n\nfunc (d *IPFS) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) {\n\tif d.Mode != \"mfs\" {\n\t\treturn nil, fmt.Errorf(\"only write in mfs mode\")\n\t}\n\tdirPath := parentDir.GetPath()\n\terr := d.sh.FilesMkdir(ctx, path.Join(dirPath, dirName), shell.FilesMkdir.Parents(true))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfile, err := d.sh.FilesStat(ctx, path.Join(dirPath, dirName))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &model.Object{ID: file.Hash, Name: dirName, Path: path.Join(dirPath, dirName), Size: int64(file.Size), IsFolder: true}, nil\n}\n\nfunc (d *IPFS) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {\n\tif d.Mode != \"mfs\" {\n\t\treturn nil, fmt.Errorf(\"only write in mfs mode\")\n\t}\n\tdstPath := path.Join(dstDir.GetPath(), path.Base(srcObj.GetPath()))","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/ipfs_api/driver.go#L94-L130","documentation":"Returned by IPFS driver MakeDir when Mode != \"mfs\". Only MFS (the mutable filesystem) supports directory creation; ipfs/ipns modes address immutable content-addressed data, so write operations are structurally impossible regardless of node permissions.","triggerScenarios":"Mounting a CID or IPNS name read-only and attempting MakeDir; leftover write calls against a storage whose mode was switched from mfs to ipfs/ipns.","commonSituations":"User points the driver at a public gateway/CID for browsing, then a sync tool tries to create folders; mode changed after objects were cached, and the UI still offers write actions.","solutions":["Switch Mode to \"mfs\" (requires a local/writable IPFS node, not a read-only gateway) if you need writes.","Otherwise remove write permissions for that mount in the host application so write actions are not attempted.","Point MakeDir-targeted workflows at a separate mfs-mode storage."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"if d.Mode != \"mfs\" {\n    return errors.New(\"MakeDir requires an mfs-mode storage with a writable local node\")\n}","typeGuard":"func isWritableMode(mode string) bool { return mode == \"mfs\" }","tryCatchPattern":"if _, err := d.MakeDir(ctx, parent, name); err != nil && strings.Contains(err.Error(), \"only write in mfs mode\") {\n    // route the operation to an mfs storage or surface read-only notice to the user\n}","preventionTips":["Restrict sync/upload tools to writable storages","Advertise mounts as read-only to the UI when mode != mfs"],"tags":["ipfs-api","read-only","mfs","write-guard"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}