pentaho/pentaho-kettle · error · KettleException
RepositoryMeta.Error.WritingMetadata
Error message
RepositoryMeta.Error.WritingMetadata
What it means
RepositoriesMeta.writeData() serializes the in-memory repository list with getXML() and writes it to the file returned by getKettleUserRepositoriesFile() (typically ~/.kettle/repositories.xml). Any exception creating or writing the FileOutputStream is wrapped in a KettleException with message "RepositoryMeta.Error.WritingMetadata" ("Error writing metadata to repositories.xml").
Solutions
- Ensure the directory ~/.kettle exists and is writable by the process user (mkdir and chown/chmod as needed).
- Check that the KETTLE_HOME / user home resolves correctly for the account running the JVM.
- Free disk space or raise the quota if the disk is full.
- Close other processes locking repositories.xml (editors, sync clients, antivirus scans).
- Inspect the wrapped cause for the precise IOException (e.g. FileNotFoundException => path/permission issue).
Example fix
// before: assumes ~/.kettle exists
repositoriesMeta.addRepository(repoMeta);
repositoriesMeta.writeData();
// after: guarantee the directory exists first
File kettleDir = new File(System.getProperty("user.home"), ".kettle");
if (!kettleDir.exists() && !kettleDir.mkdirs()) {
throw new IllegalStateException("Cannot create " + kettleDir);
}
repositoriesMeta.addRepository(repoMeta);
repositoriesMeta.writeData(); Defensive patterns
Strategy: validation
Validate before calling
File f = new File(repositoriesMeta.getKettleUserRepositoriesFile());
File dir = f.getParentFile();
if (dir != null && !dir.canWrite()) throw new IllegalStateException("Cannot write to " + dir); Try / catch
try { repositoriesMeta.writeData(); } catch (KettleException e) { log.error("Failed writing repositories.xml", e); throw new IllegalStateException("Check ~/.kettle writability and disk space", e); } Prevention
- Create ~/.kettle with correct ownership before first run
- Run services under an account with a writable HOME
- Monitor disk space/quota on hosts running PDI
- Avoid concurrent processes writing repositories.xml simultaneously
When it happens
Trigger: Calling writeData() (e.g. after addRepository() to persist a new repository definition) when the target directory does not exist, the process lacks write permission, the disk is full, or getXML() serialization fails.
Common situations: First run where ~/.kettle does not exist; read-only home directory or restricted service account (e.g. Pentaho server running as a user without a writable HOME); disk quota exceeded; antivirus locking the file on Windows.
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
- AccessInputMeta.Exception.ErrorSavingToRepository
- CloneRowMeta.Exception.UnexpectedErrorReadingStepInfo
- ColumnExistsMeta.Exception.UnableToSaveStepInfo
- ColumnExistsMeta.Exception.UnexpectedErrorReadingStepInfo
- CreditCardValidatorMeta.Exception.UnableToSaveStepInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/fe01c93911c336fe.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/repository/RepositoriesMeta.java:374
retval += conn.getXML();
}
for ( int i = 0; i < nrRepositories(); i++ ) {
RepositoryMeta ri = getRepository( i );
retval += ri.getXML();
}
retval += " </repositories>" + Const.CR;
return retval;
}
public void writeData() throws KettleException {
try {
FileOutputStream fos = new FileOutputStream( new File( getKettleUserRepositoriesFile() ) );
fos.write( getXML().getBytes() );
fos.close();
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString( PKG, "RepositoryMeta.Error.WritingMetadata" ), e );
}
}
public String toString() {
return getClass().getSimpleName();
}
public RepositoriesMeta clone() {
RepositoriesMeta meta = new RepositoriesMeta();
meta.clear();
for ( DatabaseMeta dbMeta : databases ) {
meta.addDatabase( dbMeta );
}
for ( RepositoryMeta repMeta : repositories ) {
meta.addRepository( repMeta.clone() );
}
return meta;
}View on GitHub (pinned to f3058517a1)