pentaho/pentaho-kettle · error · KettleException

GPload.Exception.DelimiterMissing

Error message

GPload.Exception.DelimiterMissing

What it means

writeLine() reads the delimiter from step metadata; if meta.getDelimiter() returns null it throws this KettleException. The delimiter is required to separate fields in the gpload data file, so writing cannot proceed without it.

Solutions

  1. Open the GPload step dialog and set the delimiter (e.g. a comma or tab) before running
  2. Fix the <delimiter> element in the .ktr XML to a concrete value
  3. If the delimiter is variable-based, ensure it resolves non-empty (see 3064) and at minimum is non-null
  4. Recreate the step with valid settings if metadata came from an incompatible PDI version

Example fix

// before (ktr XML)
<delimiter/>
// after
<delimiter>,</delimiter>
Defensive patterns

Strategy: validation

Validate before calling

if (meta.getDelimiter() == null || meta.getDelimiter().isEmpty()) {
  throw new IllegalStateException("GPload delimiter must be configured, e.g. ',' or '\\t'");
}

Type guard

boolean hasDelimiter(GPLoadMeta m) { return m.getDelimiter() != null && !m.getDelimiter().isEmpty(); }

Try / catch

try { ... } catch (KettleException e) { if (e.getMessage().contains("DelimiterMissing")) { /* set default delimiter and re-init */ } else throw e; }

Prevention

When it happens

Trigger: writeLine (via testWritiLine / normal row processing) executes while the GPload step metadata has no delimiter configured — getDelimiter() returns null.

Common situations: Step saved via a hand-edited ktr or repository where the delimiter attribute is absent; a dialog bug/older metadata format that never wrote the delimiter; someone cleared the delimiter field in the UI and saved.

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/08ea5efa1492d703. Report an issue: GitHub.

Appendix: source

Thrown at plugins/gpload/core/src/main/java/org/pentaho/di/trans/steps/gpload/GPLoadDataOutput.java:145

    Const.repl( buf, enclosure, enclosure + enclosure );
    return buf.toString();
  }

  public void writeLine( RowMetaInterface mi, Object[] row ) throws KettleException {
    if ( first ) {
      first = false;

      enclosure = meta.getEnclosure();
      if ( enclosure == null ) {
        enclosure = "";
      } else {
        enclosure = gpLoad.environmentSubstitute( enclosure );
      }

      delimiter = meta.getDelimiter();
      if ( delimiter == null ) {
        throw new KettleException( BaseMessages.getString( PKG, "GPload.Exception.DelimiterMissing" ) );
      } else {
        delimiter = gpLoad.environmentSubstitute( delimiter );
        if ( Utils.isEmpty( delimiter ) ) {
          throw new KettleException( BaseMessages.getString( PKG, "GPload.Exception.DelimiterMissing" ) );
        }
      }

      // Setup up the fields we need to take for each of the rows
      // as this speeds up processing.
      fieldNumbers = new int[meta.getFieldStream().length];
      for ( int i = 0; i < fieldNumbers.length; i++ ) {
        fieldNumbers[i] = mi.indexOfValue( meta.getFieldStream()[i] );
        if ( fieldNumbers[i] < 0 ) {
          throw new KettleException( BaseMessages.getString( PKG, "GPLoadDataOutput.Exception.FieldNotFound", meta
              .getFieldStream()[i] ) );
        }
      }

View on GitHub (pinned to f3058517a1)