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

  1. Validate the YAML first: yaml.Unmarshal into map[string]any in a scratch program or run yamllint/otelcol validate --config
  2. Replace tabs with spaces and fix indentation of nested keys (processors:, service:)
  3. If the config is empty or comments-only, pass an empty []byte — the function passes it through untouched
  4. 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

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


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/c9140efe8655bc30. Report an issue: GitHub.