{"record":{"id":"36479516ee2b8c22","repo":"SigNoz/signoz","slug":"errcodeinvalidcollectorconfig-364795","errorCode":"ErrCodeInvalidCollectorConfig","errorMessage":"failed to unmarshal collector config for pipeline wiring","messagePattern":"failed to unmarshal collector config for pipeline wiring","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"pkg/types/spantypes/spanmappersimulator.go","lineNumber":140,"sourceCode":"\t\t\t\t\t\tResource:   resourceAttrs,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn result\n}\n\n// wireSpanMapperIntoTracesPipeline appends \"signozspanmapper\" to\n// service.pipelines.traces.processors so the processor defined by\n// GenerateCollectorConfigWithSpanMapperProcessor actually runs against the\n// traces flowing through the simulator. Idempotent: skips appending if the\n// processor name is already present. Errors if the config has no traces\n// pipeline, since the simulation would otherwise silently pass spans through.\nfunc wireSpanMapperIntoTracesPipeline(confYaml []byte) ([]byte, error) {\n\tvar conf map[string]any\n\tif err := yaml.Unmarshal(confYaml, &conf); err != nil {\n\t\treturn nil, errors.Wrapf(err, errors.TypeInvalidInput, ErrCodeInvalidCollectorConfig, \"failed to unmarshal collector config for pipeline wiring\")\n\t}\n\t// Failed assertions yield nil, and indexing a nil map is safe,\n\t// so any missing/mistyped level surfaces as traces == nil below.\n\tservice, _ := conf[\"service\"].(map[string]any)\n\tpipelines, _ := service[\"pipelines\"].(map[string]any)\n\ttraces, _ := pipelines[\"traces\"].(map[string]any)\n\tif traces == nil {\n\t\treturn nil, errors.Newf(errors.TypeInternal, ErrCodeBuildMappingProcessorConfig, \"collector config has no service.pipelines.traces pipeline to wire %q into\", ProcessorName)\n\t}\n\n\tprocs, _ := traces[\"processors\"].([]any)\n\tfor _, p := range procs {\n\t\tif name, ok := p.(string); ok && name == ProcessorName {\n\t\t\treturn confYaml, nil\n\t\t}\n\t}\n\ttraces[\"processors\"] = append(procs, ProcessorName)\n","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/SigNoz/signoz/blob/5069bf80b08f1f00d7e014eccc09902f9871004f/pkg/types/spantypes/spanmappersimulator.go#L122-L158","documentation":"wireSpanMapperIntoTracesPipeline parses the collector config YAML to append the span-mapper processor to the traces pipeline; it deliberately errors if the config has no traces pipeline rather than silently passing spans through. The unmarshal failure at line 140 means the config YAML itself is unparseable.","triggerScenarios":"Running the span-mapper simulator on a config that is invalid YAML. Note the subsequent behavior: if YAML is valid but service.pipelines.traces is missing or mistyped, the code lets traces be nil and returns an error elsewhere (by design) — line 140 fires only for genuine YAML syntax/type errors.","commonSituations":"Feeding templated or user-provided configs into the simulator without validation; configs using tabs, duplicate keys, or a top-level sequence; configs serialized with yaml v2 tags incompatible with the v3 unmarshal used here.","solutions":["Validate the config YAML before simulation (yamllint or a dry yaml.Unmarshal)","Ensure the top level is a mapping with service.pipelines.traces defined so wiring can proceed","Fix tabs/duplicate keys and re-run the simulator"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"var conf map[string]any\nif err := yaml.Unmarshal(confYaml, &conf); err != nil { return err }\nif _, ok := conf[\"service\"]; !ok { /* simulator will reject: no traces pipeline */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate YAML before running the simulator","Ensure service.pipelines.traces exists in test fixtures"],"tags":["yaml","otel-collector","traces-pipeline","simulator"],"backgroundTag":"invalid-yaml-config","analyzedSha":"5069bf80b08f1f00d7e014eccc09902f9871004f","analyzedAt":"2026-08-28T06:22:12.824Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}