{"record":{"id":"ae9cf3ac6a83e0f8","repo":"apache/beam","slug":"cannot-translate-euphoria-join-operator-to-beam-ae9cf3","errorCode":null,"errorMessage":"Cannot translate Euphoria 'Join' operator to Beam transformations. Given join type '${joinType}' is not supported.","messagePattern":"Cannot translate Euphoria 'Join' operator to Beam transformations\\. Given join type '(.+?)' is not supported\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/euphoria/src/main/java/org/apache/beam/sdk/extensions/euphoria/core/translate/JoinTranslator.java","lineNumber":244,"sourceCode":"      TupleTag<LeftT> leftTag,\n      TupleTag<RightT> rightTag,\n      AccumulatorProvider accumulators) {\n    final BinaryFunctor<LeftT, RightT, OutputT> joiner = operator.getJoiner();\n    switch (operator.getType()) {\n      case INNER:\n        return new InnerJoinFn<>(\n            joiner, leftTag, rightTag, operator.getName().orElse(null), accumulators);\n      case LEFT:\n        return new LeftOuterJoinFn<>(\n            joiner, leftTag, rightTag, operator.getName().orElse(null), accumulators);\n      case RIGHT:\n        return new RightOuterJoinFn<>(\n            joiner, leftTag, rightTag, operator.getName().orElse(null), accumulators);\n      case FULL:\n        return new FullJoinFn<>(\n            joiner, leftTag, rightTag, operator.getName().orElse(null), accumulators);\n      default:\n        throw new UnsupportedOperationException(\n            String.format(\n                \"Cannot translate Euphoria '%s' operator to Beam transformations.\"\n                    + \" Given join type '%s' is not supported.\",\n                Join.class.getSimpleName(), operator.getType()));\n    }\n  }\n\n  @Override\n  PCollection<KV<KeyT, OutputT>> translate(\n      Join<LeftT, RightT, KeyT, OutputT> operator,\n      PCollection<LeftT> left,\n      PCollection<KV<KeyT, LeftT>> leftKeyed,\n      PCollection<RightT> right,\n      PCollection<KV<KeyT, RightT>> rightKeyed) {\n    final AccumulatorProvider accumulators =\n        new LazyAccumulatorProvider(AccumulatorProvider.of(leftKeyed.getPipeline()));\n    final TupleTag<LeftT> leftTag = new TupleTag<>();\n    final TupleTag<RightT> rightTag = new TupleTag<>();","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/euphoria/src/main/java/org/apache/beam/sdk/extensions/euphoria/core/translate/JoinTranslator.java#L226-L262","documentation":"JoinTranslator.getJoinFn maps Euphoria Join.Type to a concrete JoinFn (LeftOuterJoinFn, RightOuterJoinFn, FullJoinFn). Any join type outside LEFT/RIGHT/FULL falls into the default branch and throws UnsupportedOperationException, because no JoinFn exists for it in this translation path.","triggerScenarios":"Translating a Euphoria Join operator with Join.Type.INNER through JoinTranslator.getJoinFn (the CoGroup-based translation path).","commonSituations":"Migrating inner joins from other Euphoria backends (Spark/Flink) to Beam where inner join is normally the default; users assuming INNER is supported.","solutions":["Express the inner join via Join.Type.LEFT followed by filtering out null right values","Use CoGroup/Join.translate alternatives or a two-sided flat-mapping combine that supports inner semantics","Upgrade/patch Beam's euphoria extension to add an InnerJoinFn implementation","Verify the Join.Type used; only LEFT, RIGHT and FULL are accepted"],"exampleFix":"// before\nJoin.of(left, right).by(l -> l, r -> r).type(Join.Type.INNER).apply(...)\n// after\nJoin.of(left, right).by(l -> l, r -> r).type(Join.Type.LEFT).apply(...) // then filter nulls","handlingStrategy":"validation","validationCode":"if (operator.getType() != Join.Type.LEFT && operator.getType() != Join.Type.RIGHT && operator.getType() != Join.Type.FULL) { throw new IllegalArgumentException(\"JoinTranslator supports only LEFT/RIGHT/FULL\"); }","typeGuard":"boolean isSupportedJoinType(Join.Type t) { return EnumSet.of(Join.Type.LEFT, Join.Type.RIGHT, Join.Type.FULL).contains(t); }","tryCatchPattern":"try { fn = getJoinFn(operator, ...); } catch (UnsupportedOperationException e) { /* emulate INNER via LEFT join + null filter */ }","preventionTips":["Only use LEFT/RIGHT/FULL with the Euphoria-on-Beam Join operator","Emulate INNER joins by filtering outer-join nulls","Track Beam euphoria extension limitations before porting pipelines"],"tags":["unsupported-operation","join","beam","euphoria"],"backgroundTag":"unsupported-enum-value","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"}