{"record":{"id":"161a6ee5ac8c0297","repo":"wtfutil/wtf","slug":"panic-err-161a6e","errorCode":null,"errorMessage":"panic(err)","messagePattern":"panic\\(err\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/todo/widget.go","lineNumber":285,"sourceCode":"\t\tif err == nil {\n\t\t\treturn text[5:], &date\n\t\t}\n\t}\n\n\treturn text, nil\n}\n\n// persist writes the todo list to Yaml file\nfunc (widget *Widget) persist() {\n\tconfDir, _ := cfg.WtfConfigDir()\n\tfilePath := fmt.Sprintf(\"%s/%s\", confDir, widget.filePath)\n\n\tfileData, _ := yaml.Marshal(&widget.list)\n\n\terr := os.WriteFile(filePath, fileData, 0644)\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n}\n\n// setItemChecks rolls through the checklist and ensures that all checklist\n// items have the correct checked/unchecked icon per the user's preferences\nfunc (widget *Widget) setItemChecks() {\n\tfor _, item := range widget.list.Items {\n\t\titem.CheckedIcon = widget.settings.checked\n\t\titem.UncheckedIcon = widget.settings.unchecked\n\t}\n}\n\n// updateSelected sets the text of the currently-selected item to the provided text\nfunc (widget *Widget) updateSelected() {\n\tif !widget.isItemSelected() {\n\t\treturn\n\t}\n","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/modules/todo/widget.go#L267-L303","documentation":"The todo widget's persist() method marshals the widget's todo list to YAML and writes it to disk with os.WriteFile. If the write fails for any reason (permissions, missing directory, disk full), the widget panics with the raw error via panic(err). This is the module's data-persistence path, so a failure means the todo list cannot be saved.","triggerScenarios":"Any call to persist() (from deleteSelected, demoteSelected, makeSelectedLast, promoteSelected, makeSelectedFirst, or toggleChecked) where os.WriteFile returns an error: the configured saveFilePath is in a non-existent directory, the file or directory is not writable by the current user, or the disk is full.","commonSituations":"Users configure a save file path under a directory that doesn't exist or was deleted; running wtfutil with different permissions than the user who created the file (root-created file, non-root reader); read-only filesystem or full disk; wrong path in the todo module config.","solutions":["Verify the saveFilePath configured for the todo module exists and is writable by the user running wtfutil (e.g. `touch <filePath>` in a shell)","Create the missing parent directory: `mkdir -p $(dirname <filePath>)`","Fix ownership/permissions on the file or directory (chown/chmod) if a different user created it previously","Check disk space (`df -h`) and read-only mount status if the path is on a network or special filesystem"],"exampleFix":"// before\nerr := os.WriteFile(filePath, fileData, 0644)\nif err != nil {\n    panic(err)\n}\n// after\nif err := os.MkdirAll(filepath.Dir(filePath), 0755); err != nil {\n    log.Printf(\"todo: cannot create save dir: %v\", err)\n    return\n}\nif err := os.WriteFile(filePath, fileData, 0644); err != nil {\n    log.Printf(\"todo: failed to persist list: %v\", err)\n}","handlingStrategy":"validation","validationCode":"import \"os\"\n\nfunc canPersist(path string) error {\n    dir := filepath.Dir(path)\n    if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {\n        return fmt.Errorf(\"save dir missing: %s\", dir)\n    }\n    f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644)\n    if err != nil {\n        return err\n    }\n    f.Close()\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// wtfutil is a binary, not a library API; if embedding the widget code, recover around persist:\nfunc safePersist(w *Widget, path string) {\n    defer func() {\n        if r := recover(); r != nil {\n            log.Printf(\"todo persist failed: %v\", r)\n        }\n    }()\n    w.persist(path)\n}","preventionTips":["Before starting wtfutil, verify the todo module's saveFilePath exists and is writable (`ls -la`, `touch` test)","Run wtfutil under the same user account that owns the save file","Create the save directory ahead of time and avoid paths on removable/read-only mounts","Monitor disk space on the volume holding the config/save files"],"tags":["go","panic","filesystem","file-write"],"backgroundTag":"file-write-permission-denied","analyzedSha":"bb838c1ccb0f0f3223690df44afdec663d622881","analyzedAt":"2026-09-03T17:02:45.030Z","contentChangedAt":"2026-09-03T17:02:45.030Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}