{"record":{"id":"f44e74361832c999","repo":"yorukot/superfile","slug":"error-writing-pinned-directories-file-w","errorCode":null,"errorMessage":"error writing pinned directories file: %w","messagePattern":"error writing pinned directories file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/internal/ui/sidebar/pinned.go","lineNumber":57,"sourceCode":"\t\tslog.Error(\"Error parsing pinned directories data\", \"error\", err)\n\t\treturn directories\n\t}\n\n\t// Clean non-existing directories\n\tcleanedDirs := mgr.Clean(directories)\n\n\treturn cleanedDirs\n}\n\n// Save marshals and writes the pinned directories to file.\nfunc (mgr *PinnedManager) Save(dirs []directory) error {\n\tdata, err := json.Marshal(dirs)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error marshaling pinned directories: %w\", err)\n\t}\n\n\tif err := os.WriteFile(mgr.filePath, data, utils.ConfigFilePerm); err != nil {\n\t\treturn fmt.Errorf(\"error writing pinned directories file: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// Toggle adds or removes a directory from the pinned directories list\nfunc (mgr *PinnedManager) Toggle(dir string) error {\n\tdirs := mgr.Load()\n\tunPinned := false\n\n\tfor i, other := range dirs {\n\t\tif other.Location == dir {\n\t\t\tdirs = append(dirs[:i], dirs[i+1:]...)\n\t\t\tunPinned = true\n\t\t\tbreak\n\t\t}\n\t}\n","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/yorukot/superfile/blob/b72f550bc6e75913f48eb49fdd258e1a2df2fe88/src/internal/ui/sidebar/pinned.go#L39-L75","documentation":"Save marshals the pinned-directory list to JSON and writes it to mgr.filePath (the pinned.json config file). This error wraps a failure from os.WriteFile, meaning the marshaled data could not be persisted to disk. It is returned so callers like Toggle and Clean can surface a filesystem-level failure to the UI layer.","triggerScenarios":"os.WriteFile fails when writing mgr.filePath: the directory containing the file does not exist, the process lacks write permission, the disk is full, or the path is a directory/readonly mount.","commonSituations":"First run before the config directory (~/.config/...) has been created; read-only HOME or config dir; disk quota exceeded; running under a sandboxed environment without access to the config path.","solutions":["Create the parent directory before saving (os.MkdirAll(filepath.Dir(mgr.filePath), 0o755))","Check permissions on the config file/directory and fix with chmod/chown","Verify free disk space and that the path is not a read-only mount","Log the wrapped inner error (%w) to see the exact OS-level cause"],"exampleFix":"// before\nif err := os.WriteFile(mgr.filePath, data, utils.ConfigFilePerm); err != nil {\n\treturn fmt.Errorf(\"error writing pinned directories file: %w\", err)\n}\n// after\nif err := os.MkdirAll(filepath.Dir(mgr.filePath), 0o755); err != nil {\n\treturn fmt.Errorf(\"error creating config directory: %w\", err)\n}\nif err := os.WriteFile(mgr.filePath, data, utils.ConfigFilePerm); err != nil {\n\treturn fmt.Errorf(\"error writing pinned directories file: %w\", err)\n}","handlingStrategy":"validation","validationCode":"if err := os.MkdirAll(filepath.Dir(mgr.filePath), 0o755); err != nil { return err }\nif info, err := os.Stat(mgr.filePath); err == nil && info.Mode().Perm()&0o200 == 0 { return fmt.Errorf(\"pinned file not writable: %s\", mgr.filePath) }","typeGuard":null,"tryCatchPattern":"if err := mgr.Save(dirs); err != nil {\n\tvar pe *fs.PathError\n\tif errors.As(err, &pe) { log.Printf(\"write failed at %s: %v\", pe.Path, pe.Err) }\n\treturn err\n}","preventionTips":["Create the config directory at manager initialization, not at first save","Check disk space in long-running sessions before writes","Never make the config file read-only; use the manager API to edit it","Log the full error chain (%w) for OS-level diagnosis"],"tags":["go","filesystem","io","persistence"],"backgroundTag":"file-write-failed","analyzedSha":"b72f550bc6e75913f48eb49fdd258e1a2df2fe88","analyzedAt":"2026-09-01T04:38:08.254Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}