OpenNHP/opennhp · error

could not open file

Error message

could not open file: %v

What it means

AppParams.NewSmartPolicy loads the smart policy file whose path is given in AppParams.SmartPolicy. If os.Open fails - the file does not exist, the path is a directory, or read permission is missing - it returns an empty common.SmartPolicy with this wrapped error. This is invoked from runApp when the db app is run in encrypt/decrypt mode with a policy file.

Solutions

  1. Verify the path in AppParams.SmartPolicy is correct and the file exists: run `ls -l <path>`; use an absolute path to avoid cwd surprises.
  2. Check the wrapped os error: ENOENT means missing file, EISDIR means you passed a directory, EACCES means fix permissions (chmod/chown).
  3. Ensure SmartPolicy is non-empty before calling; validate the argument in runApp before constructing the policy.
  4. In containers, confirm the policy file is mounted/copied into the image at the expected path.

Example fix

// before: relative path breaks when cwd differs
app.SmartPolicy = "policy.json"
// after: resolve to absolute path and check first
abs, err := filepath.Abs(policyPath)
if err != nil { return err }
if _, err := os.Stat(abs); err != nil { return fmt.Errorf("smart policy not found: %w", err) }
app.SmartPolicy = abs
Defensive patterns

Strategy: validation

Validate before calling

if a.SmartPolicy == "" {
	return errors.New("smart policy path is empty")
}
st, err := os.Stat(a.SmartPolicy)
if err != nil { return fmt.Errorf("smart policy missing: %w", err) }
if st.IsDir() { return fmt.Errorf("%s is a directory", a.SmartPolicy) }

Type guard

func readablePolicyFile(path string) bool {
	st, err := os.Stat(path)
	return err == nil && st.Mode().IsRegular()
}

Try / catch

policy, err := appParams.NewSmartPolicy()
if err != nil {
	if errors.Is(err, fs.ErrNotExist) {
		return fmt.Errorf("smart policy file not found at %q; check the --smart-policy argument", appParams.SmartPolicy)
	}
	return err
}

Prevention

When it happens

Trigger: Calling NewSmartPolicy when: (1) the --smart-policy path does not exist or is misspelled; (2) the path points to a directory instead of a file; (3) the process lacks read permission on the policy file; (4) SmartPolicy field is empty/unset so os.Open("") fails.

Common situations: CLI invocation from a different working directory with a relative policy path; policy file not copied into a container image; typo in the TOML/CLI argument; permissions tightened after deploy.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07). Data as JSON: /api/errors/312674027e244e56. Report an issue: GitHub.

Appendix: source

Thrown at endpoints/db/utils.go:134

type AppParams struct {
	Mode                    string // the mode of operation: none, encrypt and decrypt
	Source                  string // the path of plaintext data
	DsType                  string // the type of data source: stream, online and offline
	Output                  string // path of output file
	SmartPolicy             string // path of smart policy
	Metadata                string // path of metadata
	ZtdoFilePath            string // path of ztdo file when mode is decrypt
	ZtdoId                  string // identifier of ztdo file
	DataPrivateKeyBase64    string
	AccessUrl               string // path of access url of ztdo
	ProviderPublicKeyBase64 string
}

func (a *AppParams) NewSmartPolicy() (common.SmartPolicy, error) {
	file, err := os.Open(a.SmartPolicy)
	if err != nil {
		return common.SmartPolicy{}, fmt.Errorf("could not open file: %v", err)
	}
	defer file.Close()

	fileContentByte, err := io.ReadAll(file)
	if err != nil {
		return common.SmartPolicy{}, fmt.Errorf("error reading file: %v", err)
	}

	var config common.SmartPolicy

	err = json.Unmarshal(fileContentByte, &config)
	if err != nil {
		return common.SmartPolicy{}, fmt.Errorf("json parsing error: %s", err)
	}

	spoId, err := utils.GenerateUUIDv4()
	if err != nil {
		return common.SmartPolicy{}, fmt.Errorf("error generating spoId: %v", err)

View on GitHub (pinned to 6e04ca5ff0)