pentaho/pentaho-kettle · error · RuntimeException
Exporting transformation: Couldn't create file
Error message
Exporting transformation: Couldn't create file [${filename}] What it means
When exporting a transformation from the repository explorer, the XML is written to a file via FileOutputStream. If an IOException occurs while creating or writing the file, a RuntimeException 'Exporting transformation: Couldn't create file [filename]' is thrown with the IOException as cause. It indicates the target path could not be created or written.
Solutions
- Verify the export directory exists and is writable before exporting (File.canWrite(), mkdirs)
- Check the filename/path for unresolved variables or invalid characters
- Run Pentaho/PDI with permissions to write to the target location, or choose a writable directory (e.g. user home)
- Inspect the wrapped IOException cause for the underlying OS error
Example fix
// before
String filename = "${output}/trans.ktr"; // variable not resolved
// after
String filename = Variables.getFilename(); // resolved, existing writable path
Files.createDirectories(Paths.get(filename).getParent()); Defensive patterns
Strategy: validation
Validate before calling
File f = new File(filename);
if (!f.getParentFile().exists()) f.getParentFile().mkdirs();
if (!f.getParentFile().canWrite()) throw new IllegalStateException("Not writable: " + f.getParent()); Try / catch
try { exportTransformation(filename); } catch (RuntimeException e) { if (e.getMessage().startsWith("Exporting transformation")) { showError("Check path/permissions: " + filename + " cause: " + e.getCause()); } else { throw e; } } Prevention
- Resolve all ${variables} in the filename before export
- Pre-create the target directory and test writability with File.canWrite()
- Avoid exporting to network shares or read-only locations
- Always inspect the wrapped IOException cause for the exact OS reason
When it happens
Trigger: Exporting a transformation to a filename whose parent directory does not exist, the path is a directory, the disk is full, or the process lacks write permission on the path.
Common situations: Exporting to a read-only directory or another user's folder; unresolved ${filename} variable or invalid path characters; network drive unavailable; antivirus locking the target file.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Exporting jobs: Couldn't create file
- ChangeFileEncoding.Error.CreatingFile
- ex.getMessage()
- GPLoadDataOutput.Exception" + e.getMessage()
- MailConnection.Error.SavingMessageContent
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/31bc5689a737992e.
Report an issue: GitHub.
Appendix: source
Thrown at ui/src/main/java/org/pentaho/di/ui/repository/dialog/RepositoryExplorerDialog.java:2629
for ( int i = 0; i < trans.length; i++ ) {
TransMeta ti = rep.loadTransformation( trans[i], repdir, null, true, null ); // reads last version
if ( log.isBasic() ) {
log.logBasic(
"Exporting transformation", "[" + trans[i] + "] in directory [" + repdir.getPath() + "]" );
}
String xml = XMLHandler.getXMLHeader() + ti.getXML();
String filename =
directory + repdir.getPath() + Const.FILE_SEPARATOR + fixFileName( trans[i] ) + ".ktr";
File f = new File( filename );
try {
FileOutputStream fos = new FileOutputStream( f );
fos.write( xml.getBytes( Const.XML_ENCODING ) );
fos.close();
} catch ( IOException e ) {
throw new RuntimeException( "Exporting transformation: Couldn't create file [" + filename + "]", e );
}
}
}
}
} catch ( Exception e ) {
new ErrorDialog( shell,
BaseMessages.getString( PKG, "RepositoryExplorerDialog.ExportTrans.UnexpectedError.Title" ),
BaseMessages.getString( PKG, "RepositoryExplorerDialog.ExportTrans.UnexpectedError.Message" ), e );
}
}
private String fixFileName( String filename ) {
filename = filename.replace( '/', '_' ); // do something with illegal file name chars
if ( !( "/".equals( Const.FILE_SEPARATOR ) ) ) {
filename = Const.replace( filename, Const.FILE_SEPARATOR, "_" );
}
return filename;View on GitHub (pinned to f3058517a1)