{"record":{"id":"4b450e2dd272571b","repo":"hyperledger/fabric","slug":"config-isn-t-valid","errorCode":null,"errorMessage":"config isn't valid","messagePattern":"config isn't valid","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/common/config.go","lineNumber":43,"sourceCode":"// ConfigFromFile loads the given file and converts it to a Config\nfunc ConfigFromFile(file string) (Config, error) {\n\tconfigData, err := os.ReadFile(file)\n\tif err != nil {\n\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","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/cmd/common/config.go#L25-L61","documentation":"While preparing a _bulk_docs batch write, batchUpdateDocuments() decodes each CouchDoc's jsonValue payload into a generic map so keys/attachments can be merged. If a document's jsonValue is not valid JSON, json.Unmarshal fails and the error is wrapped as 'error unmarshalling json data', aborting the whole batch update.","triggerScenarios":"Any CouchDoc in the batch whose jsonValue bytes are corrupted or non-JSON — typically a bug in code that constructed the CouchDoc (e.g. hand-built documents, custom serialization of state values) or data written by an incompatible version.","commonSituations":"Forked/patched Fabric writing raw non-JSON values as jsonValue, custom external builders (such as lvcc or custom MSP data) supplying malformed JSON, version upgrades where previously-valid encodings changed, binary data incorrectly stuffed into jsonValue.","solutions":["Find the offending document: validate each CouchDoc with json.Valid(doc.jsonValue) before batching and log the failing key","Fix the producer of the jsonValue so it writes valid JSON (use json.Marshal on a proper struct)","Inspect the ledger records for that key; if corrupt, rebuild/resync the state database","Check for version mismatches between peer binaries and previously written data","Report upstream if stock Fabric produces this — stock code paths always marshal valid JSON"],"exampleFix":"// before\ndoc := &couchDoc{jsonValue: []byte(rawValue)} // rawValue may be non-JSON\n// after\nif !json.Valid([]byte(rawValue)) {\n    return nil, fmt.Errorf(\"invalid JSON for key %s\", key)\n}\ndoc := &couchDoc{jsonValue: []byte(rawValue)}","handlingStrategy":"validation","validationCode":"for _, doc := range documents {\n    if len(doc.jsonValue) > 0 && !json.Valid(doc.jsonValue) {\n        return fmt.Errorf(\"couchDoc jsonValue is not valid JSON\")\n    }\n}","typeGuard":"func validJSONDoc(d *couchDoc) bool {\n    return len(d.jsonValue) == 0 || json.Valid(d.jsonValue)\n}","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"error unmarshalling json data\") {\n    return fmt.Errorf(\"corrupt document in batch — locate and fix producer: %w\", err)\n}","preventionTips":["Always construct jsonValue via json.Marshal of a typed struct","Run json.Valid on documents before submitting batches","Never write raw binary/non-JSON bytes as jsonValue","Test custom data producers against the couchDoc schema","After upgrades, verify legacy data still unmarshals before bulk writes"],"tags":["couchdb","json","unmarshal","fabric"],"backgroundTag":"json-unmarshal-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"}