apache/beam · error · IllegalArgumentException
The PCollection tuple must have the FhirIO.Search.OUT and Fh
Error message
The PCollection tuple must have the FhirIO.Search.OUT and FhirIO.Search.DEAD_LETTER tuple tags
What it means
FhirIO.Search.Result.of() requires the PCollectionTuple to contain both the FhirIO.Search.OUT and FhirIO.Search.DEAD_LETTER TupleTags, since FHIR search output is split into successful responses (OUT) and failed searches (DEAD_LETTER). If either tag is absent the Result wrapper cannot be constructed and an IllegalArgumentException is thrown. This is a pipeline-construction-time fail-fast check mirroring the other healthcare IO Result.of methods.
Source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/healthcare/FhirIO.java:1859
private final PCollection<KV<String, JsonArray>> keyedResources;
private final PCollection<JsonArray> resources;
private final PCollection<HealthcareIOError<String>> failedSearches;
PCollectionTuple pct;
/**
* Create FhirIO.Search.Result form PCollectionTuple with OUT and DEAD_LETTER tags.
*
* @param pct the pct
* @return the search result
* @throws IllegalArgumentException the illegal argument exception
*/
static FhirIO.Search.Result of(PCollectionTuple pct) throws IllegalArgumentException {
if (pct.has(OUT) && pct.has(DEAD_LETTER)) {
return new FhirIO.Search.Result(pct);
} else {
throw new IllegalArgumentException(
"The PCollection tuple must have the FhirIO.Search.OUT "
+ "and FhirIO.Search.DEAD_LETTER tuple tags");
}
}
private Result(PCollectionTuple pct) {
this.pct = pct;
this.keyedResources =
pct.get(OUT).setCoder(KvCoder.of(StringUtf8Coder.of(), JsonArrayCoder.of()));
this.resources =
this.keyedResources
.apply(
"Extract Values",
MapElements.into(TypeDescriptor.of(JsonArray.class)).via(KV::getValue))
.setCoder(JsonArrayCoder.of());
this.failedSearches =
pct.get(DEAD_LETTER).setCoder(HealthcareIOErrorCoder.of(StringUtf8Coder.of()));
}View on GitHub (pinned to 12126d8942)
Solutions
- Apply both tags before calling of(): pct.apply(FhirIO.Search.OUT, results) and pct.apply(FhirIO.Search.DEAD_LETTER, deadLetters)
- Use the exact constants FhirIO.Search.OUT and FhirIO.Search.DEAD_LETTER, not locally created TupleTags
- Prefer consuming the Result returned by the FhirIO.Search transform instead of hand-building the tuple
- Add pct.has(OUT) && pct.has(DEAD_LETTER) as a pre-check during development
Example fix
// before PCollectionTuple pct = PCollectionTuple.of(FhirIO.Search.OUT, searchResults); FhirIO.Search.Result r = FhirIO.Search.Result.of(pct); // throws // after pct.put(FhirIO.Search.DEAD_LETTER, failedSearches); FhirIO.Search.Result r = FhirIO.Search.Result.of(pct);
Defensive patterns
Strategy: validation
Validate before calling
if (pct.has(FhirIO.Search.OUT) && pct.has(FhirIO.Search.DEAD_LETTER)) {
FhirIO.Search.Result r = FhirIO.Search.Result.of(pct);
} Try / catch
try {
FhirIO.Search.Result r = FhirIO.Search.Result.of(pct);
} catch (IllegalArgumentException e) {
LOG.error("Tuple missing FhirIO.Search.OUT/DEAD_LETTER tags", e);
} Prevention
- Wire both OUT and DEAD_LETTER tags using the library constants
- Consume the transform's returned Result instead of rebuilding the tuple
- Add a pipeline-construction test covering FhirIO.Search wiring
When it happens
Trigger: Calling FhirIO.Search.Result.of(pct) on a PCollectionTuple missing OUT or DEAD_LETTER — e.g. manually building a tuple with only the OUT collection, or using different TupleTag instances than the FhirIO.Search constants.
Common situations: Copy-pasting tuple wiring from another connector with different tag constants; renaming tags during refactor; constructing the Result without running the FhirIO.Search transform first.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- The PCollection tuple must have the FhirIO.Read.OUT and Fhir
- The PCollection tuple bodies must have the FhirIO.Write.SUCC
- The PCollection tuple must have the DicomIO.ReadStudyMetadat
- GET request for %s returned null
- Not all temporary files are present for importing.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/563367cea2e90b48.
Report an issue: GitHub.