redis/jedis · error · IllegalStateException

ArgrepParams must be created via unbounded(), range()…

Error message

ArgrepParams must be created via unbounded(), range(), from() or to()

What it means

ArgrepParams.addParams serializes the parameter object into command arguments, but the start/end bounds must first be established via one of the factory methods unbounded(), range(), from() or to(). If startRaw or endRaw is null, the object was built without any of these, and an IllegalStateException is thrown because the wire format cannot be produced without the bounds segment.

Solutions

  1. Always initialize bounds before use: call unbounded() for a full range, or range(a,b)/from(a)/to(b) for bounded forms.
  2. Use the static factory entry points of ArgrepParams rather than raw construction so the object starts in a valid state.
  3. In tests, call the factory methods before invoking addParams/serialization.

Example fix

// before
ArgrepParams params = new ArgrepParams();
params.predicate(Predicate.equal("foo")); // no bounds -> IllegalStateException on serialization
// after
ArgrepParams params = ArgrepParams.unbounded()
    .predicate(Predicate.equal("foo")); // or ArgrepParams.range(0, 100)
Defensive patterns

Strategy: validation

Validate before calling

if (params instanceof ArgrepParams) {
  // bounds must be set via factory methods before serialization
  assertBuiltViaFactory(params);
}

Type guard

boolean hasBounds(ArgrepParams p) { return p != null; } // only instances from unbounded/range/from/to are valid

Try / catch

try {
  args = command.getCommandArguments();
} catch (IllegalStateException e) {
  if (e.getMessage().contains("ArgrepParams")) {
    params = ArgrepParams.unbounded(); // rebuild with bounds
  } else throw e;
}

Prevention

When it happens

Trigger: Constructing ArgrepParams directly (e.g. new ArgrepParams() or via a builder) and passing it to an ARGREP-based command without ever calling unbounded(), range(), from(), or to(); asserting serialization in tests before setting bounds.

Common situations: Copy-pasting param setup from another command type that has no mandatory bounds; refactoring that removed the bounds call; writing unit tests that serialize a half-initialized params object.

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 redis/jedis@6dac31d4c2 (2026-09-08). Data as JSON: /api/errors/307ae2cddb9fb2aa. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/redis/clients/jedis/params/ArgrepParams.java:254

   */
  public ArgrepParams limit(long limit) {
    this.limit = limit;
    return this;
  }

  /**
   * Perform all predicate comparisons case-insensitively.
   * @return this {@link ArgrepParams}
   */
  public ArgrepParams nocase() {
    this.nocase = true;
    return this;
  }

  @Override
  public void addParams(CommandArguments args) {
    if (startRaw == null || endRaw == null) {
      throw new IllegalStateException(
          "ArgrepParams must be created via unbounded(), range(), from() or to()");
    }
    args.add(startRaw).add(endRaw);
    for (Predicate p : predicates) {
      args.add(p.type.keyword).add(p.value);
    }
    if (combinator != null) {
      args.add(combinator);
    }
    if (limit != null) {
      args.add(Keyword.LIMIT).add(limit);
    }
    if (nocase) {
      args.add(Keyword.NOCASE);
    }
  }

  private static byte[] encode(String s) {

View on GitHub (pinned to 6dac31d4c2)