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
- Open the GPload step dialog and set the delimiter (e.g. a comma or tab) before running
- Fix the <delimiter> element in the .ktr XML to a concrete value
- If the delimiter is variable-based, ensure it resolves non-empty (see 3064) and at minimum is non-null
- 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
- Always set a delimiter when creating the GPload step — never leave it blank
- Avoid hand-editing .ktr XML; edit steps through the Spoon dialog
- Re-save GPload steps after PDI upgrades to regenerate metadata
- Validate step settings in a pre-run check hook
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
- ColumnExists.Error.TablenameFieldMissing
- exceptionMessage
- GetSubFolders.Exception.CouldnotFindField
- GetSubFolders.Log.NoField
- GPload.Exception.DataFileMissing
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)