derailed/k9s · warning · ErrCustomColumn
custom column resolution error
Error message
custom column resolution error
What it means
ErrCustomColumn is a sentinel declared in model1/helpers.go and wrapped by the custom-column renderer (render/cust_cols.go:209) as fmt.Errorf("%w: %q: %w", ErrCustomColumn, columnName, err). It means a user-defined column in views.yaml/columns config has a JSONPath expression that failed to resolve against the resource. helpers.go:85 and cust_cols_test.go:295 match it with errors.Is.
Source
Thrown at internal/model1/helpers.go:23
import (
"errors"
"fmt"
"log/slog"
"math"
"runtime"
"sort"
"strings"
"sync"
"github.com/derailed/k9s/internal/slogs"
"github.com/fvbommel/sortorder"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sruntime "k8s.io/apimachinery/pkg/runtime"
)
var ErrCustomColumn = errors.New("custom column resolution error")
// parallelRender fans work across NumCPU batch workers.
func parallelRender(n int, fn func(i int) error) error {
if n == 0 {
return nil
}
workers := min(runtime.NumCPU(), n)
if workers < 1 {
workers = 1
}
chunkSize := (n + workers - 1) / workers
var (
wg sync.WaitGroup
firstErr error
errOnce sync.Once
)View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Check the wrapped message: it names the offending column header and the underlying path error — fix that path in your views.yaml.
- Validate the JSONPath against a live object: kubectl get <res> -o jsonpath='<your-path>'.
- Keep per-GVR column definitions scoped to the resource they were written for.
Example fix
# before (views.yaml)
columns:
- name: REPLICAS
path: .spec.repicas # typo
# after
columns:
- name: REPLICAS
path: .spec.replicas Defensive patterns
Strategy: validation
Validate before calling
// validate a custom column path against a live object before adding it
func pathResolves(path string, o map[string]any) bool {
r, err := jsonpath.New("col")
if err != nil { return false }
if err := r.Parse(path); err != nil { return false }
return true
} Type guard
func isCustomColumnErr(err error) bool { return errors.Is(err, model1.ErrCustomColumn) } Try / catch
err := renderer.Render(row, o)
if errors.Is(err, model1.ErrCustomColumn) {
// message names the column; fix its path in views.yaml and re-render
} Prevention
- Test JSONPath expressions with kubectl -o jsonpath before committing views.yaml.
- Scope custom columns to the GVR whose schema you verified.
- Re-validate column configs after CRD upgrades.
When it happens
Trigger: A custom column whose path does not exist on the object (typo like $.spec.repica), syntactically invalid JSONPath, or a path valid for one GVR applied to another; rendering fails per column and the errors are joined.
Common situations: Editing views.yaml to add columns against evolving CRD schemas; copying column configs between resources with different shapes; k8s version changes renaming fields (e.g. deprecated fields removed).
Related errors
- no active context available
- expecting cronjob resource
- expecting Deployment resource
- expecting ServiceAccount resource
- expecting a context factory
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/c4c77c2006938cc6.
Report an issue: GitHub.