pentaho/pentaho-kettle · error · IllegalArgumentException

Schema string cannot be null or empty

Error message

Schema string cannot be null or empty

What it means

AvroSchemaValidator.validateSchema guards the Avro schema JSON string before parsing: a null or empty string is rejected with this IllegalArgumentException. It is a defensive security/robustness check so downstream parsing and injection scanning only run on real input.

Solutions

  1. Set the schema JSON in the step configuration before running the transformation.
  2. If using a variable/env for the schema, ensure it is defined and non-empty at runtime.
  3. Add an explicit up-front check for blank schema input in the calling code or dialog validation.
  4. Load the schema from a file/resource and verify its content length before validating.

Example fix

// before
AvroSchemaValidator.validateSchema(schemaString); // throws if empty
// after
if (schemaString == null || schemaString.trim().isEmpty()) {
  throw new IllegalArgumentException("Avro schema must be provided in step settings");
}
AvroSchemaValidator.validateSchema(schemaString);
Defensive patterns

Strategy: validation

Validate before calling

public static void requireSchema(String s) {
  if (s == null || s.trim().isEmpty()) {
    throw new IllegalArgumentException("Avro schema string must be provided and non-empty");
  }
}

Try / catch

try {
  AvroSchemaValidator.validateSchema(schemaString);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("null or empty")) {
    throw new IllegalStateException("Schema not configured in step settings");
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling validateSchema(null) or validateSchema("") — e.g. a step config field for the schema left blank, or a variable substitution resolving to empty.

Common situations: The Avro schema field in the step dialog was never filled in; an environment variable or parameter intended to hold the schema is unset and substitutes to empty string.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/dc26e70df65614e1. Report an issue: GitHub.

Appendix: source

Thrown at plugins/avro-format/core/src/main/java/org/pentaho/di/trans/steps/avro/AvroSchemaValidator.java:55

  static {
    // Java code patterns that shouldn't be in schema fields
    INJECTION_PATTERNS.add(Pattern.compile("Runtime\\.getRuntime", Pattern.CASE_INSENSITIVE));
    INJECTION_PATTERNS.add(Pattern.compile("exec\\s*\\(", Pattern.CASE_INSENSITIVE));
    INJECTION_PATTERNS.add(Pattern.compile("\\*\\s*/", Pattern.DOTALL)); // */ comment close
    INJECTION_PATTERNS.add(Pattern.compile("/\\s*\\*", Pattern.DOTALL)); // /* comment open
    INJECTION_PATTERNS.add(Pattern.compile("static\\s*\\{", Pattern.CASE_INSENSITIVE)); // static block
    INJECTION_PATTERNS.add(Pattern.compile("class\\s+\\w+", Pattern.CASE_INSENSITIVE)); // class definition
  }

  /**
   * Validates a schema string for potential code injection vulnerabilities.
   * 
   * @param schemaString the schema JSON string to validate
   * @throws IllegalArgumentException if the schema contains suspicious patterns
   */
  public static void validateSchema(String schemaString) throws IllegalArgumentException {
    if (schemaString == null || schemaString.isEmpty()) {
      throw new IllegalArgumentException("Schema string cannot be null or empty");
    }

    try {
      JsonNode schemaNode = mapper.readTree(schemaString);
      if (schemaNode.isObject()) {
        validateSchemaNode((ObjectNode) schemaNode);
      }
    } catch (IllegalArgumentException e) {
      throw e;
    } catch (Exception e) {
      throw new IllegalArgumentException("Invalid schema JSON: " + e.getMessage(), e);
    }
  }

  /**
   * Validates a schema node and all its fields for injection patterns.
   * 
   * @param node the schema node to validate

View on GitHub (pinned to f3058517a1)