{"record":{"id":"69dd1080f85a4317","repo":"OpenNHP/opennhp","slug":"json-parsing-error-s","errorCode":null,"errorMessage":"json parsing error: %s","messagePattern":"json parsing error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"endpoints/db/utils.go","lineNumber":112,"sourceCode":"\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to delete file: %v\", err)\n\t}\n\treturn nil\n}\n\nfunc (d *DataPrivateKeyStore) toJson() []byte {\n\tdataPrkStoreJson, err := json.Marshal(d)\n\tif err != nil {\n\t\treturn []byte(\"{}\")\n\t} else {\n\t\treturn dataPrkStoreJson\n\t}\n}\n\nfunc (d *DataPrivateKeyStore) fromJson(jsonData []byte) error {\n\terr := json.Unmarshal(jsonData, d)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"json parsing error: %s\", err)\n\t}\n\treturn nil\n}\n\ntype AppParams struct {\n\tMode                    string // the mode of operation: none, encrypt and decrypt\n\tSource                  string // the path of plaintext data\n\tDsType                  string // the type of data source: stream, online and offline\n\tOutput                  string // path of output file\n\tSmartPolicy             string // path of smart policy\n\tMetadata                string // path of metadata\n\tZtdoFilePath            string // path of ztdo file when mode is decrypt\n\tZtdoId                  string // identifier of ztdo file\n\tDataPrivateKeyBase64    string\n\tAccessUrl               string // path of access url of ztdo\n\tProviderPublicKeyBase64 string\n}\n","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/db/utils.go#L94-L130","documentation":"DataPrivateKeyStore.fromJson unmarshals raw JSON bytes into the DataPrivateKeyStore struct (fields dataPrivateKeyBase64, providerPublicKeyBase64). If the bytes are not valid JSON for this struct, json.Unmarshal fails and this wrapped error is returned. Note the current caller in NewDataPrivateKeyStoreWith discards this error (_ = d.fromJson(...)), so corrupted key files silently yield an empty store instead of surfacing this error.","triggerScenarios":"Calling fromJson with bytes that are: (1) not JSON at all (binary, empty file, HTML error page); (2) valid JSON but not an object with the expected fields (e.g. a JSON array or wrong schema); (3) truncated JSON from an interrupted Save/write.","commonSituations":"Key file corrupted by a crash or full disk during a previous write; user hand-edited the file and broke the JSON; wrong file passed in by mistake.","solutions":["Validate the file with `jq . <path>` or json.Valid(fileContentByte) to confirm the JSON is well-formed.","Stop ignoring the error at endpoints/db/utils.go:51 - propagate the result of d.fromJson(fileContentByte) so corrupt key files fail loudly.","Restore the key file from backup or regenerate it (Generate + Save) if it is corrupt; re-register the key with the provider.","Ensure the file contains exactly one JSON object with dataPrivateKeyBase64 and providerPublicKeyBase64 fields."],"exampleFix":"// before: parse error silently ignored\nd = &DataPrivateKeyStore{}\n_ = d.fromJson(fileContentByte)\nreturn\n// after: propagate parse failures\nif err := d.fromJson(fileContentByte); err != nil {\n\treturn nil, fmt.Errorf(\"invalid key file %s: %w\", fullPath, err)\n}\nreturn","handlingStrategy":"validation","validationCode":"content, err := os.ReadFile(path)\nif err != nil { return err }\nif !json.Valid(content) {\n\treturn fmt.Errorf(\"%s is not valid JSON\", path)\n}","typeGuard":"func isValidKeyStoreJSON(b []byte) bool {\n\tvar probe struct {\n\t\tDataPrivateKeyBase64    string `json:\"dataPrivateKeyBase64\"`\n\t\tProviderPublicKeyBase64 string `json:\"providerPublicKeyBase64\"`\n\t}\n\treturn json.Unmarshal(b, &probe) == nil\n}","tryCatchPattern":"if err := store.FromJsonChecked(content); err != nil {\n\treturn fmt.Errorf(\"corrupt key file; restore from backup or regenerate: %w\", err)\n}","preventionTips":["Stop ignoring fromJson's error in NewDataPrivateKeyStoreWith - propagate it.","Never hand-edit key files; if edits are needed, validate with jq afterwards.","Write key files atomically (temp + rename) so crashes never leave truncated JSON.","Keep backups of etc/ztdo key files."],"tags":["json","parsing","key-management"],"backgroundTag":"json-unmarshal-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"}