{"record":{"id":"8b7372a2ffa6584e","repo":"hyperledger/fabric","slug":"failed-to-marshal-config","errorCode":null,"errorMessage":"failed to marshal config","messagePattern":"failed to marshal config","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/common/config.go","lineNumber":47,"sourceCode":"\t\treturn Config{}, errors.WithStack(err)\n\t}\n\tconfig := Config{}\n\n\tif err := yaml.Unmarshal(configData, &config); err != nil {\n\t\treturn Config{}, errors.Errorf(\"error unmarshalling YAML file %s: %s\", file, err)\n\t}\n\n\treturn config, validateConfig(config)\n}\n\n// ToFile writes the config into a file\nfunc (c Config) ToFile(file string) error {\n\tif err := validateConfig(c); err != nil {\n\t\treturn errors.Wrap(err, \"config isn't valid\")\n\t}\n\tb, err := yaml.Marshal(c)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to marshal config\")\n\t}\n\tif err := os.WriteFile(file, b, 0o600); err != nil {\n\t\treturn errors.Errorf(\"failed writing file %s: %v\", file, err)\n\t}\n\treturn nil\n}\n\nfunc validateConfig(conf Config) error {\n\tnonEmptyElems := map[string]string{\n\t\t\"MSPID\":        conf.SignerConfig.MSPID,\n\t\t\"IdentityPath\": conf.SignerConfig.IdentityPath,\n\t\t\"KeyPath\":      conf.SignerConfig.KeyPath,\n\t}\n\n\tfor key, value := range nonEmptyElems {\n\t\tif value == \"\" {\n\t\t\treturn errors.Errorf(\"%s is mandatory and cannot be empty\", key)\n\t\t}","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/cmd/common/config.go#L29-L65","documentation":"batchUpdateDocuments() assembles documentMap[\"docs\"] (the array of per-document maps) and marshals it into the _bulk_docs request body with json.Marshal. Failure is wrapped as 'error marshalling json data' and the batch write is aborted. Since inputs are already decoded into plain maps/slices, failure indicates some document map still contains values Go cannot encode (channels, funcs, cycles, unsupported types).","triggerScenarios":"A batch write where one or more per-document maps (or their attachment structures) contain non-encodable values after unmarshal+merge — usually only possible via modified code paths or attachment metadata with unsupported types.","commonSituations":"Custom attachments handling that inserts unsupported types into the map, forks altering document construction, cyclic references introduced by custom data flowing into the document map.","solutions":["Marshal each document map individually in a loop to isolate the failing key and underlying error","Strip/fix non-serializable values before adding to jsonDocumentMap","Ensure attachments use the proper *Attachment struct, not raw unsupported types","Verify against stock Fabric — the stock pipeline marshals only plain maps/strings/[]byte and should never fail","Add a pre-flight json.Marshal check and skip/log offending documents rather than failing the whole batch"],"exampleFix":"// before\ndocumentMap[\"docs\"] = jsonDocumentMap\nbulkDocsJSON, err := json.Marshal(documentMap) // fails on one bad doc\n// after\nfor i, doc := range jsonDocumentMap {\n    if _, e := json.Marshal(doc); e != nil {\n        return nil, fmt.Errorf(\"document %d not marshallable: %w\", i, e)\n    }\n}\nbulkDocsJSON, err := json.Marshal(documentMap)","handlingStrategy":"validation","validationCode":"if _, err := json.Marshal(documentMap); err != nil {\n    return fmt.Errorf(\"bulk docs payload not marshallable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"error marshalling json data\") {\n    return fmt.Errorf(\"_bulk_docs payload invalid — inspect document maps: %w\", err)\n}","preventionTips":["Keep per-document maps composed of encodable primitives and []byte","Use the standard *Attachment struct for attachments","Unit-test batch assembly with json.Marshal","Avoid fork changes to document map construction","Marshal each doc individually when debugging to isolate the offender"],"tags":["couchdb","json","marshal","fabric"],"backgroundTag":"json-marshal-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}