dianping/cat · error · IOException
Can't write to an existing directory(%s)
Error message
Can't write to an existing directory(%s)
What it means
Thrown by Files.writeTo(File, byte[]) when the target File object is an existing directory. The utility refuses to open a FileOutputStream on a directory because the OS would reject it anyway; failing fast with a clear message is preferable. It is a plain IOException, so it propagates to whatever file-persistence logic called it.
Source
Thrown at cat-client/src/main/java/com/dianping/cat/support/Files.java:246
}
public String readFrom(InputStream is, String charsetName) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(16 * 1024);
copy(is, baos, AutoClose.INPUT);
return baos.toString(charsetName);
}
public String readUtf8String(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(16 * 1024);
copy(is, baos, AutoClose.INPUT);
return baos.toString("utf-8");
}
public void writeTo(File file, byte[] data) throws IOException {
if (file.isDirectory()) {
throw new IOException(String.format("Can't write to an existing directory(%s)", file));
}
Dir.INSTANCE.createDir(file.getParentFile());
FileOutputStream fos = new FileOutputStream(file);
try {
fos.write(data);
} finally {
try {
fos.close();
} catch (IOException e) {
// ignore it
}
}
}
public void writeTo(File file, String data) throws IOException {View on GitHub (pinned to e815e74d4c)
Solutions
- Log or inspect the File object right before the call: print getAbsolutePath() and isDirectory() to find why it resolves to a folder.
- Fix the path construction so it always appends a concrete file name (and extension) after the parent directory.
- If the file name is dynamic, guard it: reject empty/blank names before calling writeTo.
- As a defensive measure for races, check isDirectory() first and either delete the stray directory or pick an alternate path.
Example fix
// before File f = new File(baseDir + domain); // domain dir, no file name Files.INSTANCE.writeTo(f, bytes); // throws // after File dir = new File(baseDir, domain); File f = new File(dir, domain + ".ser"); Files.INSTANCE.writeTo(f, bytes);
Defensive patterns
Strategy: validation
Validate before calling
if (file == null || file.isDirectory()) {
throw new IllegalArgumentException("Not a writable file path: " + file);
} Try / catch
catch (IOException e) { /* message names the directory; fix path and retry once manually */ } Prevention
- Build output paths as parent-dir + explicit file-name pairs, never string-concat a bare prefix.
- Assert file names are non-empty before constructing the File.
- Unit-test path builders with empty/blank file-name inputs.
When it happens
Trigger: Calling Files.INSTANCE.writeTo(file, data) (or the convenience writeUtf8StringTo/writeCharsTo wrappers) where file.isDirectory() is true — e.g. the path points at an existing folder, or a path string was built without a file name component ("/data/cat" instead of "/data/cat/report.txt").
Common situations: Misbuilt output paths (directory prefix passed instead of full file path), a file name that is empty so getPath() resolves to the parent directory, or a race where a directory was created at the location a file was expected. Common in report/storage writers that derive file paths from domain/date concatenation.
Related errors
AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14).
Data as JSON: /api/errors/401557bc496d873d.
Report an issue: GitHub.