apache/druid · error · ExpressionValidationException

needs a positive integer as the second argument

Error message

needs a positive integer as the second argument

What it means

The RIGHT(string, n) expression function requires its second argument to be a positive whole number that fits in an int. A negative value, or a LONG too large to narrow to int without loss (yInt != y), fails validation.

Solutions

  1. Guard the length: CASE WHEN LEN(x) >= n THEN RIGHT(x, n) ELSE '' END
  2. Clamp negative values: GREATEST(n, 0)
  3. Ensure the argument is <= 2147483647 before calling
  4. Review the expression producing the length for subtraction that can go negative

Example fix

// before: RIGHT(x, LEN(x) - 10) with x shorter than 10 -> negative -> throws
// after: CASE WHEN LEN(x) >= 10 THEN RIGHT(x, LEN(x) - 10) ELSE '' END
Defensive patterns

Strategy: validation

Validate before calling

if (!(len >= 0 && len <= Integer.MAX_VALUE)) {
  throw new IllegalArgumentException("RIGHT length must be a non-negative int: " + len);
}

Type guard

static boolean validRightLen(long len) {
  return len >= 0 && len <= Integer.MAX_VALUE;
}

Prevention

When it happens

Trigger: RIGHT('abc', -1) or RIGHT('abc', 5000000000) — a negative second argument, or one exceeding Integer.MAX_VALUE.

Common situations: Length arguments computed from data (LEN(col)-N) going negative on short strings; arithmetic overflow producing huge values; literal typos.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/math/expr/Function.java:2935

    @Override
    public String name()
    {
      return "right";
    }

    @Nullable
    @Override
    public ExpressionType getOutputType(Expr.InputBindingInspector inspector, List<Expr> args)
    {
      return ExpressionType.STRING;
    }

    @Override
    protected ExprEval eval(String x, long y)
    {
      int yInt = (int) y;
      if (y < 0 || yInt != y) {
        throw validationFailed("needs a positive integer as the second argument");
      }
      int len = x.length();
      return ExprEval.ofString(y < len ? x.substring(len - yInt) : x);
    }
  }

  class LeftFunc extends StringLongFunction
  {
    @Override
    public String name()
    {
      return "left";
    }

    @Nullable
    @Override
    public ExpressionType getOutputType(Expr.InputBindingInspector inspector, List<Expr> args)
    {

View on GitHub (pinned to 9b90983fd2)