{"record":{"id":"465545b9677549da","repo":"juicedata/juicefs","slug":"one-of-srcs-is-missing","errorCode":null,"errorMessage":"one of srcs is missing","messagePattern":"one of srcs is missing","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java","lineNumber":1636,"sourceCode":"    int bufsize = 0;\n    for (int i = 0; i < srcs.length; i++) {\n      srcbytes[i] = normalizePath(srcs[i]).getBytes(\"UTF-8\");\n      bufsize += srcbytes[i].length + 1;\n    }\n    Pointer buf = Memory.allocate(Runtime.getRuntime(lib), bufsize);\n    long offset = 0;\n    for (int i = 0; i < srcs.length; i++) {\n      buf.put(offset, srcbytes[i], 0, srcbytes[i].length);\n      buf.putByte(offset + srcbytes[i].length, (byte) 0);\n      offset += srcbytes[i].length + 1;\n    }\n    int r = lib.jfs_concat(Thread.currentThread().getId(), handle, normalizePath(dst), buf, bufsize);\n    if (r < 0) {\n      if (r == ENOENT) {\n        if (!exists(dst)) {\n          throw error(r, dst);\n        } else {\n          throw new FileNotFoundException(\"one of srcs is missing\");\n        }\n      }\n      throw error(r, dst);\n    }\n  }\n\n  @Override\n  public boolean rename(Path src, Path dst) throws IOException {\n    if (needCheckPermission()) {\n      if (!superGroupFileSystem.exists(src)) {\n        return false;\n      }\n      access(src.getParent(), FsAction.WRITE);\n      Path dstAncestor = rangerPermissionChecker.getAncestor(dst).getPath();\n      access(dstAncestor, FsAction.WRITE);\n      return superGroupFileSystem.rename(src, dst);\n    }\n    statistics.incrementWriteOps(1);","sourceCodeStart":1618,"sourceCodeEnd":1654,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java#L1618-L1654","documentation":"Thrown by concat() when the native jfs_concat returns ENOENT and the destination still exists — meaning the destination is fine but at least one source file is missing. Distinguishes a missing source from a missing destination (which raises the generic error).","triggerScenarios":"A source file in srcs was deleted between validation and the native call; a path typo or wrong working directory; concurrent job/gc removed one of the sources; duplicate entries after one was already concatenated and deleted.","commonSituations":"Concurrent consumers deleting part files while a merger runs; retries after a partial first concat attempt; stale file lists built minutes before the concat executes.","solutions":["Re-verify all sources exist (fs.exists) immediately before concat","Rebuild the source list fresh at call time instead of caching","Prevent concurrent deletion (locking, ownership, or single-writer design)","Catch FileNotFoundException and retry with a refreshed source list"],"exampleFix":"// before\nfs.concat(dst, cachedSrcs);\n// after\nList<Path> present = new ArrayList<>();\nfor (Path p : cachedSrcs) if (fs.exists(p)) present.add(p);\nfs.concat(dst, present.toArray(new Path[0]));","handlingStrategy":"retry","validationCode":"for (Path s : srcs) if (!fs.exists(s)) throw new FileNotFoundException(s.toString());","typeGuard":null,"tryCatchPattern":"try { fs.concat(dst, srcs); } catch (FileNotFoundException e) { srcs = refreshList(srcs); fs.concat(dst, srcs); }","preventionTips":["Re-stat sources right before concat","Avoid concurrent consumers deleting sources","Rebuild file lists at use time, not upfront"],"tags":["java","hadoop","file-not-found"],"backgroundTag":"file-not-found","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}