{"record":{"id":"0c1d7d8ba5553f0a","repo":"SigNoz/signoz","slug":"invalid-input-0c1d7d","errorCode":"invalid_input","errorMessage":"must not specify multiple metric reader type","messagePattern":"must not specify multiple metric reader type","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/instrumentation/metric.go","lineNumber":146,"sourceCode":"\t\tif err == nil {\n\t\t\topts = append(opts, sdkmetric.WithReader(r))\n\t\t} else {\n\t\t\terrs = append(errs, err)\n\t\t}\n\t}\n\n\tif len(errs) > 0 {\n\t\treturn noop.NewMeterProvider(), noopShutdown, errors.Join(errs...)\n\t}\n\n\tmp := sdkmetric.NewMeterProvider(opts...)\n\treturn mp, mp.Shutdown, nil\n}\n\n// metricReaderWithCustomRegistry creates metric readers with custom Prometheus registry support.\nfunc metricReaderWithCustomRegistry(ctx context.Context, r contribsdkconfig.MetricReader, customRegistry *prometheus.Registry) (sdkmetric.Reader, error) {\n\tif r.Periodic != nil && r.Pull != nil {\n\t\treturn nil, errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, \"must not specify multiple metric reader type\")\n\t}\n\n\tif r.Pull != nil {\n\t\treturn pullReaderWithCustomRegistry(ctx, r.Pull.Exporter, customRegistry)\n\t}\n\treturn nil, errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, \"no valid metric reader\")\n}\n\n// pullReaderWithCustomRegistry creates pull readers with custom Prometheus registry support.\nfunc pullReaderWithCustomRegistry(ctx context.Context, exporter contribsdkconfig.MetricExporter, customRegistry *prometheus.Registry) (sdkmetric.Reader, error) {\n\tif exporter.Prometheus != nil {\n\t\treturn prometheusReaderWithCustomRegistry(ctx, exporter.Prometheus, customRegistry)\n\t}\n\n\treturn nil, errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, \"no valid metric exporter\")\n}\n","sourceCodeStart":128,"sourceCodeEnd":163,"githubUrl":"https://github.com/SigNoz/signoz/blob/5069bf80b08f1f00d7e014eccc09902f9871004f/pkg/instrumentation/metric.go#L128-L163","documentation":"Thrown by metricReaderWithCustomRegistry in the OpenMeter instrumentation package when a MetricReader config sets both Periodic and Pull. The OTel SDK config schema allows only one reader type per MetricReader entry, so specifying two is rejected as invalid input.","triggerScenarios":"Passing a contribsdkconfig.MetricReader with both r.Periodic != nil and r.Pull != nil to metricReaderWithCustomRegistry (via meterProviderWithCustomRegistry).","commonSituations":"YAML config for the metrics subsystem defines both `periodic` and `pull` blocks under the same reader; copy-pasting examples that combine a push and pull exporter in one reader entry.","solutions":["Remove either the `periodic` or `pull` block from the metric reader config so exactly one is set","If you need both push and pull metrics, define two separate metric reader entries"],"exampleFix":"// before\nreaders:\n  - periodic: { exporter: { otlp: {} } }\n    pull: { exporter: { prometheus: {} } }\n// after\nreaders:\n  - periodic: { exporter: { otlp: {} } }\n  - pull: { exporter: { prometheus: {} } }","handlingStrategy":"validation","validationCode":"if r.Periodic != nil && r.Pull != nil { return fmt.Errorf(\"specify only one of periodic or pull per metric reader\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate metric reader config in a config linter before app start","Keep push (periodic) and pull exporters in separate reader entries"],"tags":["otel","metrics","config","invalid-input"],"backgroundTag":"config-validation-failed","analyzedSha":"5069bf80b08f1f00d7e014eccc09902f9871004f","analyzedAt":"2026-08-28T06:22:12.824Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}