{"record":{"id":"2f22e669c35aca12","repo":"grpc-ecosystem/grpc-gateway","slug":"http-rules-without-a-matching-selector-s","errorCode":null,"errorMessage":"HTTP rules without a matching selector: %s","messagePattern":"HTTP rules without a matching selector: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoc-gen-grpc-gateway/main.go","lineNumber":96,"sourceCode":"\t\tif err := applyFlags(reg); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcodegenerator.SetSupportedFeaturesOnPluginGen(gen)\n\n\t\tgenerator := gengateway.New(reg, *useRequestContext, *registerFuncSuffix, *allowPatchFeature, *standalone, *useOpaqueAPI)\n\n\t\tif grpclog.V(1) {\n\t\t\tgrpclog.Infof(\"Parsing code generator request\")\n\t\t}\n\n\t\tif err := reg.LoadFromPlugin(gen); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tunboundHTTPRules := reg.UnboundExternalHTTPRules()\n\t\tif len(unboundHTTPRules) != 0 {\n\t\t\treturn fmt.Errorf(\"HTTP rules without a matching selector: %s\", strings.Join(unboundHTTPRules, \", \"))\n\t\t}\n\n\t\ttargets := make([]*descriptor.File, 0, len(gen.Request.FileToGenerate))\n\t\tfor _, target := range gen.Request.FileToGenerate {\n\t\t\tf, err := reg.LookupFile(target)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\ttargets = append(targets, f)\n\t\t}\n\n\t\tfiles, err := generator.Generate(targets)\n\t\tfor _, f := range files {\n\t\t\tif grpclog.V(1) {\n\t\t\t\tgrpclog.Infof(\"NewGeneratedFile %q in %s\", f.GetName(), f.GoPkg)\n\t\t\t}\n\n\t\t\tgenFile := gen.NewGeneratedFile(f.GetName(), protogen.GoImportPath(f.GoPkg.Path))","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/grpc-ecosystem/grpc-gateway/blob/a58a4436a376a4bcc7d8f10c4d4f919a8438bba9/protoc-gen-grpc-gateway/main.go#L78-L114","documentation":"protoc-gen-grpc-gateway's main collects HTTP rules that were declared on messages/services external to the files being generated (external HTTP rules) but were never bound to a matching RPC selector. If any remain unbound after LoadFromPlugin, generation aborts with 'HTTP rules without a matching selector'. This typically means an extended google.api.Http rule in an external proto references a method the gateway generator cannot see or that doesn't exist.","triggerScenarios":"Running protoc-gen-grpc-gateway when reg.UnboundExternalHTTPRules() returns non-empty — i.e. google.api.http annotations in files loaded via the plugin (LoadFromPlugin) whose selectors do not match any method in the files being generated or their registered dependencies.","commonSituations":"A third-party proto (or older google/api annotations.proto usage) carries http rules whose selector names a method that was renamed/deleted; generation invoked on only a subset of files so rules from a sibling file have no matching selector; typo in an http rule selector.","solutions":["Inspect the listed rule names in the error and verify each selector matches a fully-qualified RPC that exists and is included in the protoc invocation.","Remove or fix stale google.api.http rules in external protos (selector typos, renamed methods).","Include the file defining the targeted RPC in the same protoc run so the rule can bind.","If the rule is intentionally unused, delete it rather than leaving it unbound."],"exampleFix":"// before (in proto)\nextend google.api.Http { get: \"/v1/old\" } = { selector: \"svc.OldMethod\" };\n// after\nextend google.api.Http { get: \"/v1/thing\" } = { selector: \"svc.GetThing\" }; // method exists and is generated","handlingStrategy":"validation","validationCode":"// Pre-check before invoking the plugin:\ngrep -rn 'selector:' api/ | while read -r line; do\n  svc=$(echo \"$line\" | sed -E 's/.*selector: *\"([^\"]+)\".*/\\1/')\n  grep -rq \"rpc $(basename ${svc##*.})\" api/ || echo \"Unbound selector: $svc\"\ndone","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep google.api.http selectors next to the RPCs they annotate and verify on rename.","Run protoc over the full file set, never a partial subset.","Add a CI lint that extracts selectors and checks they match existing RPCs."],"tags":["codegen","http-rules","grpc-gateway","selector-mismatch"],"backgroundTag":"http-rule-selector-unbound","analyzedSha":"a58a4436a376a4bcc7d8f10c4d4f919a8438bba9","analyzedAt":"2026-09-02T10:28:31.537Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}