{"record":{"id":"d3e461a67449a9ed","repo":"netbirdio/netbird","slug":"anonymize-sync-response-w","errorCode":null,"errorMessage":"anonymize sync response: %w","messagePattern":"anonymize sync response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/internal/debug/debug.go","lineNumber":884,"sourceCode":"\n\tresolvedDomainsContent := formatResolvedDomains(resolvedDomains, g.anonymize, g.anonymizer)\n\tresolvedDomainsReader := strings.NewReader(resolvedDomainsContent)\n\tif err := g.addFileToZip(resolvedDomainsReader, \"resolved_domains.txt\"); err != nil {\n\t\treturn fmt.Errorf(\"add resolved domains file to zip: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (g *BundleGenerator) addSyncResponse() error {\n\tif g.syncResponse == nil {\n\t\tlog.Debugf(\"skipping empty sync response in debug bundle\")\n\t\treturn nil\n\t}\n\n\tif g.anonymize {\n\t\tif err := anonymizeSyncResponse(g.syncResponse, g.anonymizer); err != nil {\n\t\t\treturn fmt.Errorf(\"anonymize sync response: %w\", err)\n\t\t}\n\t}\n\n\toptions := protojson.MarshalOptions{\n\t\tEmitUnpopulated: true,\n\t\tUseProtoNames:   true,\n\t\tIndent:          \"  \",\n\t\tAllowPartial:    true,\n\t}\n\n\tg.maskSecrets()\n\n\tjsonBytes, err := options.Marshal(g.syncResponse)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"generate json: %w\", err)\n\t}\n\n\tif err := g.addFileToZip(bytes.NewReader(jsonBytes), \"network_map.json\"); err != nil {","sourceCodeStart":866,"sourceCodeEnd":902,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/internal/debug/debug.go#L866-L902","documentation":"Returned by BundleGenerator.addSyncResponse in client/internal/debug/debug.go:884 when anonymizeSyncResponse fails. That function redacts the SyncResponse in place (NetbirdConfig URIs, TURN credentials, relay/flow tokens, peer IPs, FQDNs, routes, DNS, firewall rules) and only anonymizeNetworkMap can return an error; in the current code anonymizeNetworkMap always returns nil, so this wrap is defensive. If it ever fires it signals a logic error in the anonymization walk rather than an environmental problem.","triggerScenarios":"Debug bundle generation with cfg.Anonymize true (or AnonymizeLevel >= strict) where a future or modified anonymizeNetworkMap returns an error, e.g. unparseable IP/prefix data inside the network map.","commonSituations":"Custom or in-development builds where anonymization code was extended to return errors; version combinations where network-map payloads contain fields the anonymizer cannot process.","solutions":["Regenerate the bundle with anonymization off (level none) to confirm this path is the source.","Align daemon and CLI versions so the anonymizer matches the SyncResponse shape.","If this fires on stock builds, report it: on current code the wrapped path cannot error, so it indicates modified or mismatched code."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Go: probe anonymization before committing to an anonymized bundle\nif cfg.Anonymize && deps.SyncResponse != nil {\n    if err := anonymizeSyncResponse(deps.SyncResponse, anonymizer); err != nil {\n        cfg.Anonymize = false // fall back to a non-anonymized bundle\n    }\n}","typeGuard":null,"tryCatchPattern":"// Go: switch anonymization off and regenerate if this path errors\nif err := gen.Generate(); err != nil && strings.Contains(err.Error(), \"anonymize sync response\") {\n    cfg.Anonymize = false\n    gen = debug.NewBundleGenerator(cfg, deps)\n    _, err = gen.Generate()\n}","preventionTips":["Use matching daemon/CLI/anonymizer versions.","Remember anonymization is on by default at level >= strict; disable it to isolate failures."],"tags":["go","netbird","debug-bundle","anonymization","network-map"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}