pentaho/pentaho-kettle · error · KettleStepException

Xslt.Exception.ErrorXSLFile

Error message

Xslt.Exception.ErrorXSLFile

What it means

Field-resolution failure in Xslt.processRow: XSL-file-in-field mode is active but the configured field name does not exist in the input row (indexOfValue returned a negative index), so the stylesheet location cannot be read per row.

Solutions

  1. Open the XSLT step dialog and set 'XSL filename' to a valid stylesheet path.
  2. If using variables (e.g. ${XSL_FILE}), confirm the variable is defined in the run environment/kettle.properties.
  3. Or switch 'XSL source' to field mode and supply the path via an incoming field.

Example fix

// before
XSL filename: (empty)
// after
XSL filename: ${Internal.Transformation.Filename.Directory}/transform.xsl
Defensive patterns

Strategy: validation

Validate before calling

if (!meta.useXSLField() && (meta.getXslFilename() == null || meta.getXslFilename().isEmpty())) { throw new IllegalArgumentException("XSL filename mode requires a non-empty filename"); }

Try / catch

try { step.startThreads(); } catch (KettleStepException e) { if (e.getMessage().contains("ErrorXSLFile")) { /* set the XSL filename or variable */ } }

Prevention

When it happens

Trigger: useXSLField() is false and Utils.isEmpty(meta.getXslFilename()) — 'XSL filename' box is blank in field/filename mode.

Common situations: Step dialog not fully filled in; variable used for the filename evaluates to empty at runtime after environment substitution; imported transformation lacking the xslfilename attribute.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at plugins/xml/core/src/main/java/org/pentaho/di/trans/steps/xslt/Xslt.java:127

          throw new KettleStepException( BaseMessages.getString( PKG, "Xslt.Exception.ErrorXSLFileFieldMissing" ) );
        }

        // Try to get Field index
        data.fielxslfiledposition = getInputRowMeta().indexOfValue( meta.getXSLFileField() );

        // Let's check the Field
        if ( data.fielxslfiledposition < 0 ) {
          // The field is unreachable !
          logError( BaseMessages.getString( PKG, "Xslt.Log.ErrorXSLFileFieldFinding" ) + "[" + meta.getXSLFileField()
              + "]" );
          throw new KettleStepException( BaseMessages.getString( PKG, "Xslt.Exception.ErrorXSLFileFieldFinding", meta
              .getXSLFileField() ) );
        }

      } else {
        if ( Utils.isEmpty( meta.getXslFilename() ) ) {
          logError( BaseMessages.getString( PKG, "Xslt.Log.ErrorXSLFile" ) );
          throw new KettleStepException( BaseMessages.getString( PKG, "Xslt.Exception.ErrorXSLFile" ) );
        }

        // Check if XSL File exists!
        data.xslfilename = environmentSubstitute( meta.getXslFilename() );
        FileObject file = null;
        try {
          file = KettleVFS.getInstance( getTransMeta().getBowl() ).getFileObject( data.xslfilename );
          if ( !file.exists() ) {
            logError( BaseMessages.getString( PKG, "Xslt.Log.ErrorXSLFileNotExists", data.xslfilename ) );
            throw new KettleStepException( BaseMessages.getString( PKG, "Xslt.Exception.ErrorXSLFileNotExists",
                data.xslfilename ) );
          }
          if ( file.getType() != FileType.FILE ) {
            logError( BaseMessages.getString( PKG, "Xslt.Log.ErrorXSLNotAFile", data.xslfilename ) );
            throw new KettleStepException( BaseMessages.getString( PKG, "Xslt.Exception.ErrorXSLNotAFile",
                data.xslfilename ) );
          }
        } catch ( Exception e ) {

View on GitHub (pinned to f3058517a1)