{"record":{"id":"82ebdaa66124b70f","repo":"apache/beam","slug":"builder-method-name-has-to-be-explicitly-allowed","errorCode":null,"errorMessage":"Builder method name  has to be explicitly allowed","messagePattern":"Builder method name  has to be explicitly allowed","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java","lineNumber":203,"sourceCode":"        }\n      }\n    }\n\n    // Lookup based on the method name.\n    boolean match = method.getName().equals(nameFromPayload);\n    String consideredMethodName = method.getName();\n\n    // We provide a simplification for common Java builder pattern naming convention where builder\n    // methods start with \"with\". In this case, for a builder method name in the form \"withXyz\",\n    // users may just use \"xyz\". If additional updates to the method name are needed the transform\n    // has to be updated by adding annotations.\n    if (!match && consideredMethodName.length() > 4 && consideredMethodName.startsWith(\"with\")) {\n      consideredMethodName =\n          consideredMethodName.substring(4, 5).toLowerCase() + consideredMethodName.substring(5);\n      match = consideredMethodName.equals(nameFromPayload);\n    }\n    if (match && !allowListClass.isAllowedBuilderMethod(consideredMethodName)) {\n      throw new RuntimeException(\n          \"Builder method name \" + consideredMethodName + \" has to be explicitly allowed\");\n    }\n    return match;\n  }\n\n  private Method getMethod(\n      PTransform<PInput, POutput> transform,\n      BuilderMethod builderMethod,\n      AllowedClass allowListClass) {\n\n    Row builderMethodRow = decodeRow(builderMethod.getSchema(), builderMethod.getPayload());\n\n    List<Method> matchingMethods =\n        Arrays.stream(transform.getClass().getMethods())\n            .filter(m -> isBuilderMethodForName(m, builderMethod.getName(), allowListClass))\n            .filter(m -> parametersCompatible(m.getParameters(), builderMethodRow))\n            .filter(m -> PTransform.class.isAssignableFrom(m.getReturnType()))\n            .collect(Collectors.toList());","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java#L185-L221","documentation":"A builder method matched the requested name (either directly or by the withX -> x field-name convention), but the method is not on the service's allowlist. This is the allowlist security check failing for the conventional 'withX'/field-name matching path, distinct from the @MultiLanguageBuilderMethod path.","triggerScenarios":"Expansion payload names a builder method via field-name convention (e.g. 'count' matching withCount) that exists on the transform but is not in the expansion service's allowed builder methods list.","commonSituations":"Cross-language users referencing Java transform builder methods by field name without the service operator having allowlisted them; allowlist updated for the exact method name but not the lower-cased field-name variant expected here.","solutions":["Allowlist the resolved method name (the lower-cased field name form shown in the message) in the expansion service configuration.","Rename your payload to use the exact builder method name and ensure that name is allowlisted.","Confirm with the service operator which builder methods are permitted before building the pipeline payload."],"exampleFix":"// before\npayload: {name: \"count\"}  // withCount not allowlisted\n// after: operator adds 'count' (or 'withCount') to allowed builder methods for the transform, then retry","handlingStrategy":"validation","validationCode":"String resolved = fieldName.startsWith(\"with\")\n    ? Character.toLowerCase(fieldName.charAt(4)) + fieldName.substring(5) : fieldName;\nif (!allowList.isAllowedBuilderMethod(resolved)) {\n  throw new IllegalStateException(\"Allowlist the field-name form '\" + resolved + \"' before expanding\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  return getMethod(transform, row, allowList);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"has to be explicitly allowed\")) {\n    throw new SecurityException(\"Method name not allowlisted: \" + e.getMessage(), e);\n  }\n  throw e;\n}","preventionTips":["When allowlisting withX methods, allowlist both the exact name and the derived field name if clients use field names.","Publish the effective allowlist to cross-language pipeline authors.","Version the allowlist with the transform artifact.","Add integration tests that attempt expansion of each permitted method."],"tags":["java","security","allowlist","beam-expansion-service"],"backgroundTag":"permission-denied","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}