{"record":{"id":"c2930dcabf133221","repo":"OpenNHP/opennhp","slug":"failed-to-write-json-to-file-w","errorCode":null,"errorMessage":"failed to write JSON to file: %w","messagePattern":"failed to write JSON to file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nhp/utils/utils.go","lineNumber":127,"sourceCode":"\treturn tempPath, nil\n}\n\nfunc SaveStructAsJsonFile(filePath string, data any) error {\n\tif data == nil {\n\t\treturn fmt.Errorf(\"data cannot be nil\")\n\t}\n\tif filePath == \"\" {\n\t\treturn fmt.Errorf(\"file path cannot be empty\")\n\t}\n\n\tjsonData, err := json.MarshalIndent(data, \"\", \"  \")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to marshal data to JSON: %w\", err)\n\t}\n\n\terr = os.WriteFile(filePath, jsonData, 0644) //nolint:gosec // G306: Generic utility - callers determine sensitivity\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to write JSON to file: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc LoadJsonFileAsStruct(filePath string) (any, error) {\n\tif filePath == \"\" {\n\t\treturn nil, fmt.Errorf(\"file path cannot be empty\")\n\t}\n\n\tjsonData, err := os.ReadFile(filePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read file: %w\", err)\n\t}\n\n\tvar data map[string]any\n\n\tif err := json.Unmarshal(jsonData, &data); err != nil {","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/nhp/utils/utils.go#L109-L145","documentation":"SaveStructAsJsonFile marshals any value to indented JSON and writes it with os.WriteFile. This error wraps the os.WriteFile failure, so the JSON was produced successfully but persisting it to filePath failed (bad directory, permissions, disk full, path is a directory). The underlying OS error is preserved via %w for errors.Is/As inspection.","triggerScenarios":"Calling SaveStructAsJsonFile(filePath, data) where filePath's parent directory does not exist, the process lacks write permission on the target path, the path points to a directory, or the filesystem is full/read-only.","commonSituations":"registerTAService tries to persist trust-anchor data before its config directory has been created (e.g. fresh deployment missing ~/nhp or ./etc); running the daemon as a non-root user after files were first written by root; container volumes mounted read-only; misspelled relative paths.","solutions":["Run os.MkdirAll(filepath.Dir(filePath), 0755) before calling SaveStructAsJsonFile.","Inspect the wrapped error with errors.Is(err, fs.ErrNotExist) / fs.ErrPermission to pinpoint the OS cause.","Verify the process user has write access to the target directory (ls -ld, check umask).","Check disk space and mount flags (df -h, mount | grep ro) if path and permissions look correct."],"exampleFix":"// before\nif err := utils.SaveStructAsJsonFile(\"etc/ta/ta.json\", taData); err != nil { return err }\n// after\nif err := os.MkdirAll(\"etc/ta\", 0o755); err != nil { return err }\nif err := utils.SaveStructAsJsonFile(\"etc/ta/ta.json\", taData); err != nil { return err }","handlingStrategy":"try-catch","validationCode":"if dir := filepath.Dir(path); dir != \"\" {\n    if err := os.MkdirAll(dir, 0o755); err != nil { return err }\n}\nif err := os.WriteFile(path, []byte(\"probe\"), 0o644); err != nil { /* surface before real write */ }","typeGuard":null,"tryCatchPattern":"err := utils.SaveStructAsJsonFile(path, data)\nif err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrNotExist) {\n        os.MkdirAll(filepath.Dir(path), 0o755)\n        err = utils.SaveStructAsJsonFile(path, data)\n    }\n    if err != nil { return fmt.Errorf(\"persist %s: %w\", path, err) }\n}","preventionTips":["Always create parent directories before writing generated files.","Use absolute paths derived from one configured base directory.","Check the daemon user owns or can write the target directory.","Watch disk space in deployment monitoring for hosts that write state files."],"tags":["go","filesystem","io","json"],"backgroundTag":"file-write-failed","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}