pentaho/pentaho-kettle · error · KettleException

No psql application specified

Error message

No psql application specified

What it means

createCommandLine() requires an executable path for psql in the step metadata. When meta.getPsqlpath() is null (the field was left empty), it throws this KettleException instead of attempting to build a command line. It is a required-field validation error raised by the step itself.

Solutions

  1. Open the GP Bulk Loader step settings and set the full path to the psql executable (e.g. /usr/local/greenplum-db/bin/psql).
  2. If building metadata in code, call meta.setPsqlpath(...) before execute().
  3. If loading from XML, verify the saved transformation contains the psqlpath element; re-save the step with a modern plugin version.
  4. Guard with a validation check before running the transformation to fail fast with a clearer message.

Example fix

// before (code-built meta)
GPBulkLoaderMeta meta = new GPBulkLoaderMeta();
execute(meta, true);

// after
GPBulkLoaderMeta meta = new GPBulkLoaderMeta();
meta.setPsqlpath("/usr/local/greenplum-db/bin/psql");
execute(meta, true);
Defensive patterns

Strategy: validation

Validate before calling

if (meta.getPsqlpath() == null || meta.getPsqlpath().trim().isEmpty()) {
  throw new IllegalArgumentException(
    "GP Bulk Loader: psql executable path is required before execute()");
}

Try / catch

try {
  execute(meta, wait);
} catch (KettleException e) {
  if (e.getMessage().contains("No psql application specified")) {
    meta.setPsqlpath(defaultPsqlPath());
    execute(meta, wait);
  } else throw e;
}

Prevention

When it happens

Trigger: execute() -> createCommandLine() runs with meta.getPsqlpath() == null, i.e. the 'Location of psql' / executable field in the GP Bulk Loader step was never filled in or the metadata was loaded without that attribute.

Common situations: User created the step but left the psql executable path blank; a transformation XML from an older plugin version lacks the psqlpath attribute; the step was built programmatically with GPBulkLoaderMeta without calling setPsqlpath(); wrong meta object passed in unit tests with empty defaults.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at plugins/gp-bulk-loader/core/src/main/java/org/pentaho/di/trans/steps/gpbulkloader/GPBulkLoader.java:322

   *
   * @throws KettleException
   *           Upon any exception
   */
  public String createCommandLine( GPBulkLoaderMeta meta, boolean password ) throws KettleException {
    StringBuffer sb = new StringBuffer( 300 );

    if ( meta.getPsqlpath() != null ) {
      try {
        FileObject fileObject =
          KettleVFS.getInstance( getTransMeta().getBowl() )
            .getFileObject( environmentSubstitute( meta.getPsqlpath() ), getTransMeta() );
        String psqlexec = KettleVFS.getFilename( fileObject );
        sb.append( enclosure ).append( psqlexec ).append( enclosure );
      } catch ( Exception ex ) {
        throw new KettleException( "Error retrieving sqlldr string", ex );
      }
    } else {
      throw new KettleException( "No psql application specified" );
    }

    if ( meta.getControlFile() != null ) {
      try {
        FileObject fileObject =
          KettleVFS.getInstance( getTransMeta().getBowl() )
            .getFileObject( environmentSubstitute( meta.getControlFile() ), getTransMeta() );

        sb.append( " -n -f " );
        sb.append( enclosure ).append( KettleVFS.getFilename( fileObject ) ).append( enclosure );
      } catch ( Exception ex ) {
        throw new KettleException( "Error retrieving controlfile string", ex );
      }
    } else {
      throw new KettleException( "No control file specified" );
    }

    if ( meta.getLogFile() != null ) {

View on GitHub (pinned to f3058517a1)