pentaho/pentaho-kettle · error · KettleStepException

DynamicSQLRowMeta.Exception.UnableToDetermineQueryFields

Error message

DynamicSQLRowMeta.Exception.UnableToDetermineQueryFields

What it means

DynamicSQLRowMeta.getFields determines the fields returned by the SQL by executing db.getQueryFields(realSQL, false); if that throws KettleDatabaseException it wraps it in a KettleStepException with this message key plus the offending SQL. It signals the step could not infer its output row shape from the database.

Solutions

  1. Test the SQL template directly against the database (with variables resolved) to see the underlying DB error
  2. Check DB connection (host, credentials, driver) used by the step
  3. Fix the SQL so the query fields can be determined (ensure the SELECT list is resolvable)
  4. Enable variable substitution consistently or fix the variable values in the environment

Example fix

// before
SELECT * FROM ${schema}.orders WHERE dt = '?'   // unresolved schema variable
// after
set ${schema} in the run configuration (e.g. schema=public) or hard-code: SELECT * FROM public.orders WHERE dt = ?
Defensive patterns

Strategy: try-catch

Validate before calling

// Smoke-test the SQL (with variables resolved) before metadata analysis:
Database db = new Database(loggingObject, meta.getDatabaseMeta());
db.connect();
RowMetaInterface fields = db.getQueryFields(space.environmentSubstitute(meta.getSql()), false);
db.disconnect();

Try / catch

try {
  stepMeta.getStepMetaInterface().getFields(row, origin, info, target, space, repository, metaStore);
} catch (KettleStepException e) {
  logError("Could not determine query fields — verify SQL and DB connection", e);
  throw e;
}

Prevention

When it happens

Trigger: During metadata analysis (e.g. analyseImpact) or step output-field calculation, when the SQL (after optional environment variable substitution via replacevars) fails to execute or be parsed by the database for field discovery.

Common situations: Invalid SQL template in the step; database unreachable or credentials wrong; variable substitution producing broken SQL; SQL syntax valid at runtime with parameters but not parseable by getQueryFields.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/dynamicsqlrow/DynamicSQLRowMeta.java:235

    if ( databaseMeta == null ) {
      return;
    }

    Database db = new Database( loggingObject, databaseMeta );
    databases = new Database[] { db }; // Keep track of this one for cancelQuery

    // First try without connecting to the database... (can be S L O W)
    // See if it's in the cache...
    RowMetaInterface add = null;
    String realSQL = sql;
    if ( replacevars ) {
      realSQL = space.environmentSubstitute( realSQL );
    }
    try {
      add = db.getQueryFields( realSQL, false );
    } catch ( KettleDatabaseException dbe ) {
      throw new KettleStepException( BaseMessages.getString(
        PKG, "DynamicSQLRowMeta.Exception.UnableToDetermineQueryFields" )
        + Const.CR + sql, dbe );
    }

    if ( add != null ) { // Cache hit, just return it this...
      for ( int i = 0; i < add.size(); i++ ) {
        ValueMetaInterface v = add.getValueMeta( i );
        v.setOrigin( name );
      }
      row.addRowMeta( add );
    } else {
      // No cache hit, connect to the database, do it the hard way...
      try {
        db.connect();
        add = db.getQueryFields( realSQL, false );
        for ( int i = 0; i < add.size(); i++ ) {
          ValueMetaInterface v = add.getValueMeta( i );
          v.setOrigin( name );

View on GitHub (pinned to f3058517a1)