{"record":{"id":"81afd1444a3ec69a","repo":"grpc/grpc-go","slug":"extproc-incorrect-override-config-type-provided","errorCode":null,"errorMessage":"extproc: incorrect override config type provided (%T): %v","messagePattern":"extproc: incorrect override config type provided \\(%T\\): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/httpfilter/extproc/ext_proc.go","lineNumber":245,"sourceCode":"\ntype clientFilter struct {\n\tmetricsRecorder estats.MetricsRecorder\n\ttarget          string\n}\n\nfunc (clientFilter) Close() {}\n\nfunc (cf *clientFilter) BuildClientInterceptor(base, override httpfilter.FilterConfig) (httpfilter.ClientInterceptor, error) {\n\tb, ok := base.(baseConfig)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"extproc: incorrect config type provided (%T): %v\", base, base)\n\t}\n\n\tvar ov overrideConfig\n\tif override != nil {\n\t\tov, ok = override.(overrideConfig)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"extproc: incorrect override config type provided (%T): %v\", override, override)\n\t\t}\n\t}\n\n\tconfig := newInterceptorConfig(b, ov)\n\n\t// Create a channel to the external processor server.\n\tcc, cancel, err := iextproc.CreateExtProcChannel(config.server)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"extproc: failed to create channel to the external processor server %q: %v\", config.server.TargetURI, err)\n\t}\n\treturn &clientInterceptor{\n\t\tconfig:          config,\n\t\tprocClient:      v3procservicegrpc.NewExternalProcessorClient(cc),\n\t\tcloseClient:     cancel,\n\t\tmetricsRecorder: cf.metricsRecorder,\n\t\ttarget:          cf.target,\n\t}, nil\n}","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/httpfilter/extproc/ext_proc.go#L227-L263","documentation":"Raised by BuildClientInterceptor when a per-route override config is present but is not the overrideConfig type produced by ParseFilterConfigOverride. Mirrors the base-config invariant: the override must be an overrideConfig or nil.","triggerScenarios":"BuildClientInterceptor is called with a non-nil override whose concrete type is not overrideConfig — typically a registry/type-URL collision dispatching the override through the wrong builder, or a test passing a hand-rolled FilterConfig.","commonSituations":"Override produced by a different filter's ParseFilterConfigOverride due to overlapping TypeURLs. Tests that build a clientInterceptor with an arbitrary override struct. A refactor where overrideConfig changed but a stale producer remains.","solutions":["Ensure the override, when non-nil, comes from extproc's ParseFilterConfigOverride (returns overrideConfig).","In tests, pass either nil or a real overrideConfig value.","Resolve any TypeURL collision so the extproc ExtProcPerRoute URL is handled only by the extproc builder."],"exampleFix":"// before (test): arbitrary override\ncf.BuildClientInterceptor(base, wrongOverride{})\n\n// after\ncf.BuildClientInterceptor(base, overrideConfig{})  // or nil","handlingStrategy":"type-guard","validationCode":"func isOverrideConfig(c httpfilter.FilterConfig) bool { _, ok := c.(overrideConfig); return ok }","typeGuard":"func isOverrideConfig(c httpfilter.FilterConfig) bool { _, ok := c.(overrideConfig); return ok }","tryCatchPattern":null,"preventionTips":["Source override config from extproc's ParseFilterConfigOverride or pass nil.","Avoid TypeURL collisions between filters."],"tags":["extproc","xds","config-parsing","type-mismatch","per-route"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}