derailed/k9s · error

failed to process label selector template: %w

Error message

failed to process label selector template: %w

What it means

The jump rule's labelSelector field is rendered through applyTemplate(rule.LabelSelector, sourceObj) against the source object's unstructured map. Rendering failed — typically the template references a field that does not exist on the object (map lookup miss) or uses syntax the mini-template engine rejects. The %w carries the template error detail.

Source

Thrown at internal/view/custom_jump.go:60

	if mv, ok := customViewers[targetGVR]; ok {
		if mv.viewerFn != nil {
			v = mv.viewerFn(targetGVR)
		} else {
			v = NewBrowser(targetGVR)
			if mv.enterFn != nil {
				v.GetTable().SetEnterFn(mv.enterFn)
			}
		}
	} else {
		v = NewScaleExtender(NewOwnerExtender(NewBrowser(targetGVR)))
	}

	// Build label selector if specified
	var labelSel labels.Selector
	if rule.LabelSelector != "" {
		labelStr, labelErr := applyTemplate(rule.LabelSelector, sourceObj)
		if labelErr != nil {
			return fmt.Errorf("failed to process label selector template: %w", labelErr)
		}
		labelSel, labelErr = labels.Parse(labelStr)
		if labelErr != nil {
			return fmt.Errorf("invalid label selector: %w", labelErr)
		}
	}

	// Set label selector if we have one
	if labelSel != nil {
		v.SetLabelSelector(labelSel, true)
	}

	// Build field selector if specified
	var fieldSel string
	if rule.FieldSelector != "" {
		var fieldErr error
		fieldSel, fieldErr = applyTemplate(rule.FieldSelector, sourceObj)
		if fieldErr != nil {

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Inspect the actual object (kubectl get <gvr> <name> -o yaml) and confirm every referenced field exists
  2. Point the template at fields guaranteed present, e.g. {{ .metadata.name }} or {{ .metadata.namespace }}
  3. If you do not need substitution, use a static selector string with no {{ }} at all

Example fix

// before (k9s config, jumps rule)
labelSelector: "app={{ .metadata.labels.app }},tier={{ .spec.tier }}"
// after — only reference fields that exist on every source object
labelSelector: "app={{ .metadata.labels.app }}"
Defensive patterns

Strategy: validation

Validate before calling

// dry-run the template against a live object before configuring the rule
obj, _ := fetchResourceObject(app, sourceGVR, sourcePath)
if _, err := applyTemplate(rule.LabelSelector, obj); err != nil {
    return fmt.Errorf("labelSelector template invalid: %w", err)
}

Prevention

When it happens

Trigger: A jump rule like labelSelector: "app={{ .metadata.labels.app }}" used on a source object that has no metadata.labels.app key; referencing nested paths absent from the fetched object; template placeholders with unsupported functions.

Common situations: Rules authored against one resource kind (Deployments with tier labels) reused on kinds lacking those labels; CRDs with different metadata shapes; quoting mistakes in k9s config YAML that mangle the {{ }} placeholders.

Related errors


AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15). Data as JSON: /api/errors/2be5a277ec1cd244. Report an issue: GitHub.