caddyserver/caddy · error

not implemented

Error message

not implemented

What it means

celHTTPRequest adapts *http.Request to CEL (the expression language used by the `expression` matcher / match_expression). The ref.Val interface requires ConvertToType, but requests only support native conversion (ConvertToNative) and their own type; asking CEL to convert a request to another type hits an unimplemented path and panics.

Source

Thrown at modules/caddyhttp/celmatcher.go:308

type celHTTPRequest struct{ *http.Request }

func (cr celHTTPRequest) ResolveName(name string) (any, bool) {
	if name == CELRequestVarName {
		return cr, true
	}
	return nil, false
}

func (cr celHTTPRequest) Parent() interpreter.Activation {
	return nil
}

func (cr celHTTPRequest) ConvertToNative(typeDesc reflect.Type) (any, error) {
	return cr.Request, nil
}

func (celHTTPRequest) ConvertToType(typeVal ref.Type) ref.Val {
	panic("not implemented")
}

func (cr celHTTPRequest) Equal(other ref.Val) ref.Val {
	if o, ok := other.Value().(celHTTPRequest); ok {
		return types.Bool(o.Request == cr.Request)
	}
	return types.ValOrErr(other, "%v is not comparable type", other)
}
func (celHTTPRequest) Type() ref.Type { return httpRequestCELType }
func (cr celHTTPRequest) Value() any  { return cr }

var pkixNameCELType = cel.ObjectType("pkix.Name", traits.ReceiverType)

// celPkixName wraps a pkix.Name with
// methods to satisfy the ref.Val interface.
type celPkixName struct{ *pkix.Name }

func (pn celPkixName) ConvertToNative(typeDesc reflect.Type) (any, error) {

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Rewrite the expression to use request fields instead of converting the whole request: request.method == "GET", request.header["x"]...
  2. Use the documented request properties (method, path, query, headers) rather than treating request as a scalar
  3. Test expressions with caddy adapt or a small CEL harness before deploying

Example fix

# before
match expression {
    expression string(request) contains "admin"
}
# after
match expression {
    expression request.uri.path.contains("admin")
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Writing a CEL expression in match_expression that coerces the request object to a non-native type, e.g. `request + "x"`, `string(request)`, or passing request where a different CEL type is expected and a conversion is attempted.

Common situations: Users writing CEL matchers assuming the request auto-converts to string/map; expressions mixing request with other types via operators that trigger ConvertToType; upgrading from older CEL go-lang versions with different conversion semantics.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/bcd160fa20a3ad33. Report an issue: GitHub.