{"record":{"id":"0cd15aa977476f71","repo":"OpenNHP/opennhp","slug":"failed-to-read-file-w","errorCode":null,"errorMessage":"failed to read file: %w","messagePattern":"failed to read file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nhp/utils/utils.go","lineNumber":140,"sourceCode":"\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 {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal JSON %s to struct: %w\", string(jsonData), err)\n\t}\n\n\treturn data, nil\n}\n\nfunc UpdateTomlConfig(filePath string, key string, value any) error {\n\tcontent, err := os.ReadFile(filePath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar newContent string","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/nhp/utils/utils.go#L122-L158","documentation":"LoadJsonFileAsStruct reads the file with os.ReadFile and wraps any read failure. This means the path was non-empty but the OS could not open/read it - typically the file does not exist, or permission prevents reading, or the path is a directory. The OS error is wrapped with %w.","triggerScenarios":"Calling LoadJsonFileAsStruct with a path whose file was never created (e.g. SaveStructAsJsonFile was never run or failed), a typo'd path, or a file readable only by root while the daemon runs as a lower-privileged user.","commonSituations":"registerTAService runs on first boot before the trust-anchor file is generated; key/TA file rotated or deleted externally; working-directory difference makes relative paths resolve elsewhere; NFS/permission issues in container deployments.","solutions":["Check the file exists at the exact path (ls -l / os.Stat) before loading; create it via SaveStructAsJsonFile if absent.","Match errors with errors.Is(err, fs.ErrNotExist) vs fs.ErrPermission to decide between 'generate it' and 'fix permissions'.","Use absolute paths built from a known base directory instead of relative paths that depend on the daemon's CWD.","Fix ownership/permissions (chown/chmod) so the daemon's user can read the file."],"exampleFix":"// before\nraw, err := utils.LoadJsonFileAsStruct(\"etc/ta.json\")\n// after\nif _, statErr := os.Stat(\"etc/ta.json\"); errors.Is(statErr, fs.ErrNotExist) {\n    if mkErr := utils.SaveStructAsJsonFile(\"etc/ta.json\", defaultTA); mkErr != nil { return mkErr }\n}\nraw, err := utils.LoadJsonFileAsStruct(\"etc/ta.json\")","handlingStrategy":"validation","validationCode":"if info, err := os.Stat(path); err != nil {\n    return fmt.Errorf(\"TA file missing: %w\", err)\n} else if info.IsDir() {\n    return fmt.Errorf(\"%s is a directory\", path)\n}","typeGuard":null,"tryCatchPattern":"data, err := utils.LoadJsonFileAsStruct(path)\nif err != nil {\n    if errors.Is(err, fs.ErrNotExist) { /* generate default file, retry once */ }\n    else if errors.Is(err, fs.ErrPermission) { /* report permission problem */ }\n}","preventionTips":["Ensure any file you read is created (by SaveStructAsJsonFile or provisioning) before first load.","Use absolute paths independent of the process working directory.","Match wrapped fs errors to distinguish not-exist from permission-denied.","Keep ownership/permissions consistent across deploy steps."],"tags":["go","filesystem","io"],"backgroundTag":"file-read-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"}