apache/beam · error · IllegalArgumentException

2xx codes should not be exceptions. Got status code

Error message

2xx codes should not be exceptions. Got status code: %s with body: %s

What it means

HealthcareApiClient.HealthcareHttpException represents an HTTP error response from the Healthcare API. Its private constructor guards its own invariant: a 2xx status code must never be wrapped as an exception. If constructed with a 2xx code, it throws IllegalArgumentException — a bug guard indicating the caller misclassified a successful response as an error.

Solutions

  1. Fix the caller so it only constructs HealthcareHttpException for status codes >= 300 (or non-2xx).
  2. Guard before construction: if (statusCode / 100 != 2) throw new HealthcareHttpException(...).
  3. If you see this at runtime, log the status code and body and check where the status is parsed — the response was actually successful.
  4. Prefer a helper like fromResponse(response) that classifies status codes once, centrally.

Example fix

// before
throw new HealthcareApiClient.HealthcareHttpException(response.getStatusCode(), body); // throws if 2xx

// after
if (response.getStatusCode() / 100 != 2) {
  throw new HealthcareApiClient.HealthcareHttpException(response.getStatusCode(), body);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (statusCode / 100 == 2) {
  // success: do not build HealthcareHttpException
  return;
}

Try / catch

try {
  throw new HealthcareApiClient.HealthcareHttpException(statusCode, body);
} catch (IllegalArgumentException e) {
  LOG.error("Status {} was a success code; error path misclassified", statusCode, e);
}

Prevention

When it happens

Trigger: Code constructs HealthcareHttpException with a status code in the 200–299 range together with a response body — i.e., an error-handling path was invoked for an actually successful response.

Common situations: Custom status-code handling logic that checks only 'code != 200' or misparses the status before wrapping; refactored client code where a success path is accidentally routed to error construction; tests or wrappers building the exception manually with canned status codes.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/c72c87f9c5ad5d34. 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:596

        .datasets()
        .fhirStores()
        .fhir()
        .executeBundle(fhirStore, httpBody)
        .execute();
  }

  /**
   * Wraps {@link HttpResponse} in an exception with a statusCode field for use with {@link
   * HealthcareIOError}.
   */
  public static class HealthcareHttpException extends Exception {
    private final int statusCode;

    private HealthcareHttpException(int statusCode, String message) {
      super(message);
      this.statusCode = statusCode;
      if (statusCode / 100 == 2) {
        throw new IllegalArgumentException(
            String.format(
                "2xx codes should not be exceptions. Got status code: %s with body: %s",
                statusCode, message));
      }
    }

    /**
     * Creates an exception from a non-OK response.
     *
     * @param statusCode the HTTP status code.
     * @param message the error message.
     * @return the healthcare http exception
     */
    static HealthcareHttpException of(int statusCode, String message) {
      return new HealthcareHttpException(statusCode, message);
    }

    int getStatusCode() {

View on GitHub (pinned to 12126d8942)