{"record":{"id":"bcd160fa20a3ad33","repo":"caddyserver/caddy","slug":"not-implemented","errorCode":null,"errorMessage":"not implemented","messagePattern":"not implemented","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddyhttp/celmatcher.go","lineNumber":308,"sourceCode":"type celHTTPRequest struct{ *http.Request }\n\nfunc (cr celHTTPRequest) ResolveName(name string) (any, bool) {\n\tif name == CELRequestVarName {\n\t\treturn cr, true\n\t}\n\treturn nil, false\n}\n\nfunc (cr celHTTPRequest) Parent() interpreter.Activation {\n\treturn nil\n}\n\nfunc (cr celHTTPRequest) ConvertToNative(typeDesc reflect.Type) (any, error) {\n\treturn cr.Request, nil\n}\n\nfunc (celHTTPRequest) ConvertToType(typeVal ref.Type) ref.Val {\n\tpanic(\"not implemented\")\n}\n\nfunc (cr celHTTPRequest) Equal(other ref.Val) ref.Val {\n\tif o, ok := other.Value().(celHTTPRequest); ok {\n\t\treturn types.Bool(o.Request == cr.Request)\n\t}\n\treturn types.ValOrErr(other, \"%v is not comparable type\", other)\n}\nfunc (celHTTPRequest) Type() ref.Type { return httpRequestCELType }\nfunc (cr celHTTPRequest) Value() any  { return cr }\n\nvar pkixNameCELType = cel.ObjectType(\"pkix.Name\", traits.ReceiverType)\n\n// celPkixName wraps a pkix.Name with\n// methods to satisfy the ref.Val interface.\ntype celPkixName struct{ *pkix.Name }\n\nfunc (pn celPkixName) ConvertToNative(typeDesc reflect.Type) (any, error) {","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddyhttp/celmatcher.go#L290-L326","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Rewrite the expression to use request fields instead of converting the whole request: request.method == \"GET\", request.header[\"x\"]...","Use the documented request properties (method, path, query, headers) rather than treating request as a scalar","Test expressions with caddy adapt or a small CEL harness before deploying"],"exampleFix":"# before\nmatch expression {\n    expression string(request) contains \"admin\"\n}\n# after\nmatch expression {\n    expression request.uri.path.contains(\"admin\")\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use request.field accessors, never convert request itself","Dry-run expressions with caddy adapt / a CEL REPL","Pin and read the CEL matcher docs for available request properties"],"tags":["caddy","cel","expression-matcher","caddyfile","runtime-panic"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}