{"record":{"id":"8c44d65a372867f0","repo":"apache/beam","slug":"input-has-tags-actualinputtags-but-expected-input-tags","errorCode":null,"errorMessage":"Input has tags ${actualInputTags} but expected input tags ${inputTags}","messagePattern":"Input has tags (.+?) but expected input tags (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/yaml/src/main/java/org/apache/beam/sdk/extensions/yaml/YamlTransform.java","lineNumber":146,"sourceCode":"   * Indicates that this YamlTransform expects multiple, named outputs.\n   *\n   * @param outputTags the set of expected output tags to this transform\n   * @return a PTransform like this but with a {@link PCollectionRowTuple} output type.\n   */\n  public YamlTransform<InputT, PCollectionRowTuple> withMultipleOutputs(String... outputTags) {\n    return new YamlTransform<InputT, PCollectionRowTuple>(\n        yamlDefinition, inputTags, ImmutableSet.copyOf(outputTags));\n  }\n\n  @Override\n  public OutputT expand(InputT input) {\n    if (inputTags != null) {\n      Set<String> actualInputTags =\n          input.expand().keySet().stream()\n              .map(TupleTag::getId)\n              .collect(Collectors.toCollection(HashSet::new));\n      if (!inputTags.equals(actualInputTags)) {\n        throw new IllegalArgumentException(\n            \"Input has tags \"\n                + Joiner.on(\", \").join(actualInputTags)\n                + \" but expected input tags \"\n                + Joiner.on(\", \").join(inputTags));\n      }\n    }\n\n    // There is no generic apply...\n    POutput output;\n    @SuppressWarnings(\"rawtypes\")\n    PTransform externalTransform =\n        PythonExternalTransform.from(\"apache_beam.yaml.yaml_transform.YamlTransform\")\n            .withArgs(yamlDefinition)\n            .withExtraPackages(ImmutableList.of(\"jinja2\", \"pyyaml\", \"virtualenv-clone\"));\n    if (input instanceof PBegin) {\n      output = ((PBegin) input).apply(externalTransform);\n    } else if (input instanceof PCollection) {\n      output = ((PCollection<?>) input).apply(externalTransform);","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/yaml/src/main/java/org/apache/beam/sdk/extensions/yaml/YamlTransform.java#L128-L164","documentation":"YamlTransform.expand validates that the PCollections fed into the externally-defined transform carry exactly the input tags declared in the YAML spec. The library joins the actual TupleTag ids and the expected set and throws IllegalArgumentException when the two sets differ. This fail-fast check prevents wiring a transform with missing or misnamed inputs.","triggerScenarios":"Calling YamlTransform.expand (or a wrapper) with a PCollectionRowTuple whose input tag ids do not exactly match the input tags expected by the YAML transform definition — extra tags, missing tags, or renamed tags all trip the check.","commonSituations":"YAML schema declares inputs like 'input' but the pipeline supplies tags 'input' and 'side_input'; renaming a PCollection's output tag; composing YAML transforms programmatically where tag ids are auto-generated and don't match the spec.","solutions":["Align the input PCollectionRowTuple tags with the input tags declared in the YAML transform spec (extra or missing tags both fail).","Rename the upstream transform's output TupleTag ids so they match the YAML-declared input tags.","Update the YAML spec's input tags to the tags your pipeline actually produces, if the spec is wrong.","Print both tag sets (the message lists them) and diff to find the mismatched tag."],"exampleFix":"// before\nPCollectionRowTuple.of(\"in\", pc).apply(yamlTransform);\n// after (YAML expects tag \"input\")\nPCollectionRowTuple.of(\"input\", pc).apply(yamlTransform);","handlingStrategy":"validation","validationCode":"Set<String> declared = new HashSet<>(yamlSpecInputs);\nSet<String> actual = inputTuple.expand().keySet().stream().map(TupleTag::getId).collect(Collectors.toSet());\nif (!declared.equals(actual)) throw new IllegalStateException(\"Input tag mismatch: \" + actual + \" vs \" + declared);","typeGuard":"boolean hasExpectedTags(PCollectionRowTuple t, Set<String> expected) {\n  return t.expand().keySet().stream().map(TupleTag::getId).collect(Collectors.toSet()).equals(expected);\n}","tryCatchPattern":"try {\n  result = pipeline.apply(yamlTransform);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Input has tags\")) { /* fix tag wiring */ }\n  throw e;\n}","preventionTips":["Keep input tag names in YAML spec and pipeline code in a shared constant","Log TupleTag ids of inputs before applying YAML transforms","Diff spec inputs against actual tags in CI tests"],"tags":["apache-beam","java","yaml-transform","validation"],"backgroundTag":"invalid-argument-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"}