jaegertracing/jaeger · error
filter term cannot be encoded for the wire
Error message
filter term cannot be encoded for the wire
What it means
ErrTermNotEncodable is a sentinel error wrapped with the offending Go type (%T) when fromFilterExpression meets a filter term it has no wire representation for: either a nil term or a Go type the package does not recognize. It signals the filter tree was not finalized into the shape ToProto expects.
Source
Thrown at internal/proto/expression/v1/convert.go:207
case *expression.Call:
if term == nil {
break
}
call, err := ToProto(term)
if err != nil {
return nil, err
}
return &Expression{Term: &Expression_Call{Call: call}}, nil
}
if scalar := fromFilterConstant(expr); scalar != nil {
return &Expression{Term: &Expression_Scalar{Scalar: scalar}}, nil
}
return nil, fmt.Errorf("%w: %T", ErrTermNotEncodable, expr)
}
// ErrTermNotEncodable is returned for a term ToProto has no wire form for: a nil one, or a type
// this package does not know. Both mean the tree was not the finalized filter ToProto expects.
var ErrTermNotEncodable = errors.New("filter term cannot be encoded for the wire")
// fromFilterConstant writes a constant node as the wire's spelling plus the hint that fits it. A
// duration and an instant have no hint of their own, so they travel as an unhinted constant in
// the syntax the field they are compared against is written in — Go duration syntax and RFC 3339
// — which is the spelling the receiving side reads them back from.
// It returns nil for a term that is not a constant, and for a constant that holds nothing: a nil
// pointer of a constant type reads through the Expression interface as a constant of that type, and
// reading its value would panic. The caller answers a nil with ErrTermNotEncodable, which is what a
// tree carrying one deserves.
func fromFilterConstant(expr expression.Expression) *Scalar {
switch term := expr.(type) {
case *expression.AnyValue:
if term == nil {
return nil
}
return &Scalar{Value: term.Value}
case *expression.StringValue:
if term == nil {View on GitHub (pinned to 806f444784)
Solutions
- Inspect the wrapped %T in the error and replace that term type with one of the supported finalized filter term types.
- Run the filter tree through the package's finalization/normalization step before calling ToProto.
- In callers, use errors.Is(err, exprv1.ErrTermNotEncodable) to detect this case and return a 400-style validation error to the user.
- Check for nil terms in the tree before encoding.
Example fix
// before
if err != nil { return err }
// after
if err != nil {
if errors.Is(err, exprv1.ErrTermNotEncodable) {
return httperr.BadRequest("unsupported filter term")
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
func encodable(t FilterTerm) bool { return t != nil && isSupportedTermType(t) } Type guard
func isSupportedTerm(t any) bool {
switch t.(type) {
case nil:
return false
default:
return isFinalizedTerm(t)
}
} Try / catch
pb, err := ToProto(tree)
if errors.Is(err, ErrTermNotEncodable) {
return fmt.Errorf("filter term %w; finalize the tree first", err)
} Prevention
- Finalize filter trees with the package's finalization step before ToProto.
- Check for nil terms before encoding.
- Use errors.Is against ErrTermNotEncodable to surface user-facing validation errors.
When it happens
Trigger: Calling ToProto on a filter expression containing a nil term or a term type outside the package's known set (e.g. an unfinalized/internal node type); tests TestToProto_RefusesATermItCannotWrite and TestQueryParametersRefuseAnUnsendableFilter exercise this.
Common situations: Passing a query filter tree built by hand or by an older API version directly to ToProto without running the finalization step; constructing query parameters with unsupported comparison nodes.
Related errors
- filter argument is empty: a call argument must carry a call
- filter argument is empty: exactly one of attr, field, nested
- %w: it does not support the operator %q
- %w: it does not index the %q level
- %w: it evaluates a conjunction of predicates only
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/51bba4ec5b3ba215.
Report an issue: GitHub.