SigNoz/signoz · error
ErrCodeInvalidCollectorConfig
ErrCodeInvalidCollectorConfig
Error message
failed to unmarshal collector config
What it means
GenerateCollectorConfigWithLLMPricingProcessor takes the agent's current collector config as YAML, and if non-empty (after TrimSpace) tries to yaml.Unmarshal it into map[string]any before injecting the LLM pricing processor. Failure means the existing config is not valid YAML (or not a mapping), so it cannot be programmatically modified.
Source
Thrown at pkg/types/llmpricingruletypes/processorconfig.go:118
CacheWrite: aiobservabilitytypes.SignozGenAICostCacheWrite,
Total: aiobservabilitytypes.SignozGenAITotalCost,
},
}
}
// GenerateCollectorConfigWithLLMPricingProcessor injects (or replaces) the signozllmpricing
// processor block in the collector YAML with one built from the given rules.
func GenerateCollectorConfigWithLLMPricingProcessor(
currentConfYaml []byte,
rules []*LLMPricingRule,
) ([]byte, error) {
if len(bytes.TrimSpace(currentConfYaml)) == 0 {
return currentConfYaml, nil
}
var collectorConf map[string]any
if err := yaml.Unmarshal(currentConfYaml, &collectorConf); err != nil {
return nil, errors.Wrapf(err, errors.TypeInvalidInput, ErrCodeInvalidCollectorConfig, "failed to unmarshal collector config")
}
// rare but don't do anything in this case, also means it's just comments.
if collectorConf == nil {
return currentConfYaml, nil
}
processors := map[string]any{}
if existing, ok := collectorConf["processors"]; ok && existing != nil {
p, ok := existing.(map[string]any)
if !ok {
return nil, errors.Newf(errors.TypeInvalidInput, ErrCodeInvalidCollectorConfig, "collector config 'processors' must be a mapping, got %T", existing)
}
processors = p
}
processors[ProcessorName] = buildProcessorConfig(rules)
collectorConf["processors"] = processors
View on GitHub (pinned to 5069bf80b0)
Solutions
- Validate the YAML first: yaml.Unmarshal into map[string]any in a scratch program or run yamllint/otelcol validate --config
- Replace tabs with spaces and fix indentation of nested keys (processors:, service:)
- If the config is empty or comments-only, pass an empty []byte — the function passes it through untouched
- Regenerate the config from a known-good template rather than patching the broken one
Example fix
# before (tabs) processors: redaction: # after (spaces) processors: redaction:
Defensive patterns
Strategy: validation
Validate before calling
var m map[string]any
if err := yaml.Unmarshal(currentConfYaml, &m); err != nil {
return fmt.Errorf("collector config is not valid YAML: %w", err)
} Prevention
- Lint collector configs (yamllint / otelcol validate) before feeding to config generators
- Never use tabs in YAML
- Pass empty []byte for empty configs so passthrough applies
When it happens
Trigger: Calling RecommendAgentConfig (or this function directly) when the passed currentConfYaml contains YAML syntax errors, tabs used for indentation, duplicate keys, or a top-level scalar instead of a mapping.
Common situations: Users hand-editing odigos/otel collector config with tab indentation; configs with anchors/aliases malformed after templating; passing a JSON-with-BOM or binary content; passing a config whose top level is a list.
Related errors
- ErrCodeInvalidCollectorConfig
- ErrCodeInvalidCollectorConfig
- ErrCodeInvalidResolver
- ErrCodeInvalidGatewayConfig
- invalid_input
AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28).
Data as JSON: /api/errors/c9140efe8655bc30.
Report an issue: GitHub.