{"record":{"id":"3623edd8636bd041","repo":"OpenNHP/opennhp","slug":"failed-to-marshal-data-to-json-w","errorCode":null,"errorMessage":"failed to marshal data to JSON: %w","messagePattern":"failed to marshal data to JSON: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nhp/utils/utils.go","lineNumber":122,"sourceCode":"\n\tif err := file.Close(); err != nil {\n\t\treturn \"\", err\n\t}\n\n\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)","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/nhp/utils/utils.go#L104-L140","documentation":"After input validation, SaveStructAsJsonFile marshals the data with json.MarshalIndent; if marshaling fails (e.g. unsupported types like channels, funcs, or cyclic data), the error is wrapped as 'failed to marshal data to JSON: %w' preserving the underlying cause. The file is not written in this case.","triggerScenarios":"Passing data containing unserializable values: channels, complex, func values, NaN/Inf floats, cyclic references, or a custom MarshalJSON that errors.","commonSituations":"Struct fields holding time.Ticker channels or function pointers added during refactors; plugin payloads with opaque fields; map[string]any filled from external sources containing unsupported values.","solutions":["Read the wrapped %w cause to find the offending field/type","Remove or replace unserializable fields (channels, funcs, cycles)","Add json:\"-\" tags on fields that must not be serialized","Pre-flight with json.Marshal in tests covering the payload type"],"exampleFix":"// before\ntype TA struct{ Stop chan struct{} }\nSaveStructAsJsonFile(path, ta)\n// after\ntype TA struct {\n    Stop chan struct{} `json:\"-\"`\n}\nSaveStructAsJsonFile(path, ta)","handlingStrategy":"try-catch","validationCode":"if _, err := json.Marshal(data); err != nil { return fmt.Errorf(\"payload unserializable: %w\", err) }","typeGuard":null,"tryCatchPattern":"var serr *json.UnsupportedTypeError\nif err := SaveStructAsJsonFile(path, data); err != nil {\n    if errors.As(err, &serr) { log.Error(\"field type not serializable: %v\", serr.Value) }\n    return err\n}","preventionTips":["Keep serializable structs free of channels, funcs, and cycles","Tag internal-only fields with json:\"-\"","Add round-trip marshal tests for payload types","Use errors.As/errors.Is to unwrap the %w cause"],"tags":["json","serialization","marshaling"],"backgroundTag":"json-marshal-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"}