{"record":{"id":"21e39999ce0b14ab","repo":"apache/beam","slug":"envoyratelimiterfactory-requires-envoyratelimitercontext-got","errorCode":null,"errorMessage":"EnvoyRateLimiterFactory requires EnvoyRateLimiterContext, got: ","messagePattern":"EnvoyRateLimiterFactory requires EnvoyRateLimiterContext, got: ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/components/src/main/java/org/apache/beam/sdk/io/components/ratelimiter/EnvoyRateLimiterFactory.java","lineNumber":121,"sourceCode":"  }\n\n  @Override\n  public RateLimiter getLimiter(RateLimiterContext context) {\n    if (!(context instanceof EnvoyRateLimiterContext)) {\n      throw new IllegalArgumentException(\n          \"EnvoyRateLimiterFactory requires EnvoyRateLimiterContext\");\n    }\n    return new EnvoyRateLimiter(this, (EnvoyRateLimiterContext) context);\n  }\n\n  @Override\n  public boolean allow(RateLimiterContext context, int permits)\n      throws IOException, InterruptedException {\n    if (permits == 0) {\n      return true;\n    }\n    if (!(context instanceof EnvoyRateLimiterContext)) {\n      throw new IllegalArgumentException(\n          \"EnvoyRateLimiterFactory requires EnvoyRateLimiterContext, got: \"\n              + context.getClass().getName());\n    }\n    checkArgument(permits >= 0, \"Permits must be non-negative\");\n    EnvoyRateLimiterContext envoyContext = (EnvoyRateLimiterContext) context;\n    return fetchTokens(envoyContext, permits);\n  }\n\n  private boolean fetchTokens(EnvoyRateLimiterContext context, int tokens)\n      throws IOException, InterruptedException {\n\n    init();\n    RateLimitServiceGrpc.RateLimitServiceBlockingStub currentStub = stub;\n    if (currentStub == null) {\n      throw new IllegalStateException(\"RateLimitServiceStub is null\");\n    }\n\n    Map<String, String> descriptors = context.getDescriptors();","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/components/src/main/java/org/apache/beam/sdk/io/components/ratelimiter/EnvoyRateLimiterFactory.java#L103-L139","documentation":"EnvoyRateLimiterFactory.allow(context, permits) checks that the supplied RateLimiterContext is an EnvoyRateLimiterContext and, if not, throws IllegalArgumentException including the offending context's class name. Unlike getLimiter, this variant is called per-request on the hot path, so the check runs on every allow() invocation.","triggerScenarios":"Calling allow() with a non-Envoy RateLimiterContext implementation, e.g. one produced by a different RateLimiterFactory or a hand-rolled subclass of RateLimiterContext.","commonSituations":"Shared rate-limiter plumbing that passes a generic context to whichever factory is configured; swapping the factory to Envoy without changing the context construction code.","solutions":["Pass an EnvoyRateLimiterContext (built with the required descriptors) to allow().","Use EnvoyRateLimiterFactory.getLimiter(context) once to obtain a RateLimiter instead of calling allow() with raw contexts.","The error message includes the actual class name — confirm which implementation is being constructed upstream and fix it at the source."],"exampleFix":"// before\nboolean ok = envoyFactory.allow(RateLimiterContext.create(), 1); // throws\n// after\nboolean ok = envoyFactory.allow(EnvoyRateLimiterContext.builder().setDescriptors(d).build(), 1);","handlingStrategy":"type-guard","validationCode":"if (!(ctx instanceof EnvoyRateLimiterContext)) {\n  throw new IllegalArgumentException(\"allow() requires EnvoyRateLimiterContext, got \" + ctx.getClass().getName());\n}","typeGuard":"static EnvoyRateLimiterContext asEnvoyContext(RateLimiterContext ctx) {\n  return ctx instanceof EnvoyRateLimiterContext ? (EnvoyRateLimiterContext) ctx : null;\n}","tryCatchPattern":"try {\n  allowed = factory.allow(ctx, permits);\n} catch (IllegalArgumentException e) {\n  LOG.error(\"Wrong context type: {}\", e.getMessage()); // includes offending class name\n}","preventionTips":["Bind one factory to one context type in pipeline configuration.","Call getLimiter() once and use the returned RateLimiter instead of raw allow().","Read the class name in the message to find where the wrong context is built."],"tags":["rate-limiting","envoy","grpc","type-check"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}