OpenNHP/opennhp · error
failed to read file
Error message
failed to read file: %w
What it means
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.
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.
Example fix
// before
raw, err := utils.LoadJsonFileAsStruct("etc/ta.json")
// after
if _, statErr := os.Stat("etc/ta.json"); errors.Is(statErr, fs.ErrNotExist) {
if mkErr := utils.SaveStructAsJsonFile("etc/ta.json", defaultTA); mkErr != nil { return mkErr }
}
raw, err := utils.LoadJsonFileAsStruct("etc/ta.json") Defensive patterns
Strategy: validation
Validate before calling
if info, err := os.Stat(path); err != nil {
return fmt.Errorf("TA file missing: %w", err)
} else if info.IsDir() {
return fmt.Errorf("%s is a directory", path)
} Try / catch
data, err := utils.LoadJsonFileAsStruct(path)
if err != nil {
if errors.Is(err, fs.ErrNotExist) { /* generate default file, retry once */ }
else if errors.Is(err, fs.ErrPermission) { /* report permission problem */ }
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- failed to read file content
- failed to write JSON to file
- resource not found
- error reading file
- could not get file info
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/0cd15aa977476f71.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/utils/utils.go:140
return fmt.Errorf("failed to marshal data to JSON: %w", err)
}
err = os.WriteFile(filePath, jsonData, 0644) //nolint:gosec // G306: Generic utility - callers determine sensitivity
if err != nil {
return fmt.Errorf("failed to write JSON to file: %w", err)
}
return nil
}
func LoadJsonFileAsStruct(filePath string) (any, error) {
if filePath == "" {
return nil, fmt.Errorf("file path cannot be empty")
}
jsonData, err := os.ReadFile(filePath)
if err != nil {
return nil, fmt.Errorf("failed to read file: %w", err)
}
var data map[string]any
if err := json.Unmarshal(jsonData, &data); err != nil {
return nil, fmt.Errorf("failed to unmarshal JSON %s to struct: %w", string(jsonData), err)
}
return data, nil
}
func UpdateTomlConfig(filePath string, key string, value any) error {
content, err := os.ReadFile(filePath)
if err != nil {
return err
}
var newContent stringView on GitHub (pinned to 6e04ca5ff0)