apache/druid · error · java.lang.IllegalStateException

Not an error; check isError first

Error message

Not an error; check isError first

What it means

Either.error() returns the error (left) value only when this Either actually represents an error. Calling it on a value-holding Either breaks the contract, so an IllegalStateException is thrown telling the developer to check isError() first.

Solutions

  1. Call isError() before accessing error()
  2. Use valueOr / map / fold-style accessors that handle both sides
  3. If you expected an error, inspect upstream logic that produced the Either

Example fix

// before
ErrorType err = either.error();
// after
if (either.isError()) {
  ErrorType err = either.error();
  handle(err);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (either.isError()) { /* safe to call either.error() */ }

Type guard

if (either.isError()) {
  ErrorType err = either.error();
} else {
  ValueType val = either.value();
}

Try / catch

try {
  return either.error();
} catch (IllegalStateException e) {
  return defaultError; // Either held a value, not an error
}

Prevention

When it happens

Trigger: Calling either.error() without first calling either.isError(), on an Either that holds a value.

Common situations: Misreading the Either contract after a map()/value() call; assuming error() returns null instead of throwing when a value is present; refactors that change which side is populated.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/87d8a08c45e717f0. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/java/util/common/Either.java:76

    return error == null;
  }

  public boolean isError()
  {
    return error != null;
  }

  /**
   * Returns the error object.
   *
   * @throws IllegalStateException if this instance is not an error
   */
  public L error()
  {
    if (isError()) {
      return error;
    } else {
      throw new IllegalStateException("Not an error; check isError first");
    }
  }

  /**
   * If this Either represents a value, returns it. If this Either represents an error, throw an error.
   *
   * If the error is a {@link DruidException}, it is thrown. If it is some other {@link Throwable}, it is
   * wrapped in a {@link DruidException} and thrown. If it is not a throwable, a generic {@link DruidException}
   * is thrown containing the string representation of the error object.
   *
   * To retrieve the error as-is, use {@link #isError()} and {@link #error()} instead.
   */
  @Nullable
  public R valueOrThrow()
  {
    if (isValue()) {
      return value;
    } else if (error instanceof Throwable) {

View on GitHub (pinned to 9b90983fd2)