apache/beam · error · NoSuchElementException

Error listing HL7v2 Messages from

Error message

Error listing HL7v2 Messages from %s: %s

What it means

HttpHealthcareApiClient's HL7v2 message listing paginator wraps any IOException from the Cloud Healthcare API call in a NoSuchElementException so the Java Stream/Iterator contract can be preserved. The original API error message is embedded in the formatted message, so the root cause (network, permissions, bad store name) is in the trailing %s.

Solutions

  1. Check the hl7v2Store path string matches projects/{project}/locations/{location}/datasets/{dataset}/hl7V2Stores/{store} exactly
  2. Grant the service account the roles/healthcare.hl7v2StoreViewer (or messages.list) permission
  3. Log/unwrap the embedded IOException message (the text after the second colon) for the real cause
  4. Verify store exists with `gcloud healthcare hl7v2-stores describe` and check network/firewall and retry for transient errors

Example fix

// before
throw new NoSuchElementException(String.format("Error listing HL7v2 Messages from %s: %s", hl7v2Store, e.getMessage()));
// after
// catch NoSuchElementException and log getCause/message; validate the store path first
try {
  new HttpHealthcareApiClient().listMessages(hl7v2Store, filter, pageToken);
} catch (IOException check) {
  throw new IllegalArgumentException("Invalid or inaccessible hl7v2Store: " + hl7v2Store, check);
}
Defensive patterns

Strategy: try-catch

Validate before calling

java
if (!hl7v2Store.matches("projects/[^/]+/locations/[^/]+/datasets/[^/]+/hl7V2Stores/[^/]+")) {
  throw new IllegalArgumentException("Malformed hl7v2Store path: " + hl7v2Store);
}

Try / catch

java
try {
  iterator.next();
} catch (NoSuchElementException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Error listing HL7v2 Messages")) {
    throw new IOException("HL7v2 listing failed for " + storePath + ": " + e.getMessage(), e);
  }
  throw e; // genuine end-of-iteration
}

Prevention

When it happens

Trigger: Iterating HL7v2 messages via HL7v2MessagePages.next() when the underlying healthcare.projects.locations.datasets.hl7V2Stores.messages.list call throws IOException: bad hl7v2Store path, missing IAM roles (healthcare.hl7V2StoreViewer), network failure, quota exhaustion, or 4xx/5xx from the API.

Common situations: Typo in the projects/{p}/locations/{l}/datasets/{d}/hl7V2Stores/{s} path; service account lacking healthcare.hl7V2Stores.get/messages.list; transient network errors in long-running Beam pipelines; store deleted mid-pipeline.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/58e7624459e39dcd. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/healthcare/HttpHealthcareApiClient.java:889

                    hl7v2Store, e.getMessage()));
          }
        }
        return this.pageToken != null;
      }

      @Override
      public List<HL7v2Message> next() throws NoSuchElementException {
        try {
          ListMessagesResponse response =
              makeListRequest(client, hl7v2Store, start, end, filter, orderBy, pageToken);
          this.isFirstRequest = false;
          this.pageToken = response.getNextPageToken();
          List<Message> msgs = response.getHl7V2Messages();

          return msgs.stream().map(HL7v2Message::fromModel).collect(Collectors.toList());
        } catch (IOException e) {
          this.pageToken = null;
          throw new NoSuchElementException(
              String.format(
                  "Error listing HL7v2 Messages from %s: %s", hl7v2Store, e.getMessage()));
        }
      }
    }
  }

  /** The type FhirResourcePagesIterator for methods which return paged output. */
  public static class FhirResourcePagesIterator implements Iterator<JsonArray> {

    public enum FhirMethod {
      SEARCH,
      PATIENT_EVERYTHING
    }

    private final FhirMethod fhirMethod;
    private final String fhirStore;
    private final String resourceType;

View on GitHub (pinned to 12126d8942)