juicedata/juicefs · error · HadoopIllegalArgumentException
Source file " + normalizePath(src) + " is no
Error message
Source file " + normalizePath(src)
+ " is not in the same directory with the target "
+ normalizePath(dst) What it means
Thrown by concat() when a source path is not in the same parent directory as the destination. JuiceFS's native concat requires all files in the same directory, so the wrapper pre-validates each src's parent against dst's parent and rejects mismatches with HadoopIllegalArgumentException.
Source
Thrown at sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java:1612
@Override
public void concat(final Path dst, final Path[] srcs) throws IOException {
if (needCheckPermission()) {
access(dst.getParent(), FsAction.WRITE);
access(dst, FsAction.WRITE);
for (Path src : srcs) {
access(src, FsAction.READ);
}
superGroupFileSystem.concat(dst, srcs);
return;
}
statistics.incrementWriteOps(1);
if (srcs.length == 0) {
throw new IllegalArgumentException("No sources given");
}
Path dp = makeQualified(dst).getParent();
for (Path src : srcs) {
if (!makeQualified(src).getParent().equals(dp)) {
throw new HadoopIllegalArgumentException("Source file " + normalizePath(src)
+ " is not in the same directory with the target "
+ normalizePath(dst));
}
}
byte[][] srcbytes = new byte[srcs.length][];
int bufsize = 0;
for (int i = 0; i < srcs.length; i++) {
srcbytes[i] = normalizePath(srcs[i]).getBytes("UTF-8");
bufsize += srcbytes[i].length + 1;
}
Pointer buf = Memory.allocate(Runtime.getRuntime(lib), bufsize);
long offset = 0;
for (int i = 0; i < srcs.length; i++) {
buf.put(offset, srcbytes[i], 0, srcbytes[i].length);
buf.putByte(offset + srcbytes[i].length, (byte) 0);
offset += srcbytes[i].length + 1;
}
int r = lib.jfs_concat(Thread.currentThread().getId(), handle, normalizePath(dst), buf, bufsize);View on GitHub (pinned to c9a67b23e8)
Solutions
- Move/copy the source files into the destination directory before concat
- Choose a dst in the same directory as the sources
- Rename sources to the target directory via fs.rename before concatenating
- Batch sources per-directory and run one concat per directory
Example fix
// before
fs.concat(new Path("/data/out/final"), new Path[]{new Path("/tmp/part-0")});
// after
fs.rename(new Path("/tmp/part-0"), new Path("/data/out/part-0"));
fs.concat(new Path("/data/out/final"), new Path[]{new Path("/data/out/part-0")}); Defensive patterns
Strategy: validation
Validate before calling
Path dp = dst.getParent(); for (Path s : srcs) if (!s.getParent().equals(dp)) throw new IllegalArgumentException("source not in dst dir: " + s); Type guard
boolean sameDir(Path dst, Path src) { return dst.getParent().equals(src.getParent()); } Try / catch
try { fs.concat(dst, srcs); } catch (HadoopIllegalArgumentException e) { /* relocate sources then retry */ } Prevention
- Qualify all paths with makeQualified before comparing parents
- Group files by directory before merging
- Rename cross-directory sources into the destination first
When it happens
Trigger: concat(dst, src) where src lives in a different directory than dst; using relative paths resolved differently from the qualified dst; programmatically mixing paths from multiple directories.
Common situations: Merging part files spread across subdirectories; users expecting HDFS-like cross-directory concat; staging files in /tmp then concatenating into a final directory.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- No sources given
- Invalid start or len parameter
- stream was closed
- arguments: " + off + " " + len
- position is negative
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/6daa8d60dd5638f3.
Report an issue: GitHub.