flowable/flowable-engine · error · org.activiti.engine.ActivitiException
Couldn't write file
Error message
Couldn't write file ${filePath} What it means
IoUtil.writeStringToFile writes a string to a classpath-resolved file via BufferedOutputStream. Any exception — including failure resolving the file (see getFile) or an I/O write/flush error — is wrapped in ActivitiException 'Couldn't write file <filePath>' with the original cause chained.
Solutions
- Check the chained cause (e.getCause()) to distinguish resolution vs. write failure.
- Ensure the target location is a writable directory on the filesystem, not inside a jar.
- Grant write permissions to the process user for the target directory.
- Use plain java.nio (Files.writeString) with a real filesystem path for non-classpath targets.
Example fix
// before
IoUtil.writeStringToFile(content, "output/result.txt"); // read-only dir
// after
Path target = Paths.get(System.getProperty("java.io.tmpdir"), "result.txt");
Files.writeString(target, content); Defensive patterns
Strategy: try-catch
Validate before calling
Path dir = Paths.get(outputDir);
if (!Files.isWritable(dir)) throw new IllegalStateException("Not writable: " + dir); Try / catch
try {
IoUtil.writeStringToFile(content, path);
} catch (ActivitiException e) {
if (e.getMessage().startsWith("Couldn't write file")) {
Throwable c = e.getCause();
if (c != null && String.valueOf(c.getMessage()).contains("Permission")) { /* fix permissions */ }
}
} Prevention
- Never write into classpath/jar locations; resolve a real writable filesystem path first
- Pre-create the target directory and verify write permissions for the runtime user
- Prefer java.nio.file.Files.write for application output instead of classpath-relative helpers
When it happens
Trigger: Calling IoUtil.writeStringToFile(content, filePath) where getFile(filePath) fails (resource not on classpath) or FileOutputStream/write/flush throws (read-only directory, permissions, disk full).
Common situations: Trying to write into a jar or immutable classpath location; read-only deployment directory; missing write permissions for the process user.
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
- Couldn't write file
- An error occurs creating a web-service client for WSDL '" +…
- Bundle cannot be generated
- byte array for resource
- byte array for resource
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/0fcf4841a1ae7bf8.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/util/IoUtil.java:80
}
public static File getFile(String filePath) {
URL url = IoUtil.class.getClassLoader().getResource(filePath);
try {
return new File(url.toURI());
} catch (Exception e) {
throw new ActivitiException("Couldn't get file " + filePath + ": " + e.getMessage());
}
}
public static void writeStringToFile(String content, String filePath) {
BufferedOutputStream outputStream = null;
try {
outputStream = new BufferedOutputStream(new FileOutputStream(getFile(filePath)));
outputStream.write(content.getBytes());
outputStream.flush();
} catch (Exception e) {
throw new ActivitiException("Couldn't write file " + filePath, e);
} finally {
IoUtil.closeSilently(outputStream);
}
}
/**
* Closes the given stream. The same as calling {@link InputStream#close()}, but errors while closing are silently ignored.
*/
public static void closeSilently(InputStream inputStream) {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException ignore) {
// Exception is silently ignored
}
}
View on GitHub (pinned to d6d39ce1c6)