{"record":{"id":"8b7d557fd388a1ca","repo":"github/copilot-sdk","slug":"filesystem-does-not-support-atomic-moves-cannot-s","errorCode":null,"errorMessage":"Filesystem does not support atomic moves; cannot safely publish runtime to ","messagePattern":"Filesystem does not support atomic moves; cannot safely publish runtime to ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/ffi/NativeRuntimeLoader.java","lineNumber":85,"sourceCode":"         *            fully-written temporary file in the same directory as\n         *            {@code cached}\n         * @param cached\n         *            intended final location\n         * @throws IOException\n         *             if the move fails\n         */\n        void publish(Path temp, Path cached) throws IOException;\n    }\n\n    /**\n     * Production publisher: {@link Files#move} with\n     * {@link StandardCopyOption#ATOMIC_MOVE}.\n     */\n    static final AtomicPublisher DEFAULT_PUBLISHER = (temp, cached) -> {\n        try {\n            Files.move(temp, cached, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);\n        } catch (AtomicMoveNotSupportedException ex) {\n            throw new IllegalStateException(\"Filesystem does not support atomic moves; cannot safely publish \"\n                    + RUNTIME_FILENAME + \" to \" + cached, ex);\n        } catch (FileAlreadyExistsException | AccessDeniedException ex) {\n            // Windows can report AccessDeniedException instead of\n            // FileAlreadyExistsException when another publisher wins the race.\n            try {\n                if (isValidCachedFile(cached)) {\n                    return;\n                }\n            } catch (IOException ignored) {\n                // fall through to the error below\n            }\n            throw new IllegalStateException(\n                    \"Concurrent extraction race: target already exists but is not a valid file: \" + cached, ex);\n        }\n    };\n\n    private NativeRuntimeLoader() {\n    }","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/ffi/NativeRuntimeLoader.java#L67-L103","documentation":"NativeRuntimeLoader's DEFAULT_PUBLISHER publishes the extracted runtime to its cache location using Files.move with ATOMIC_MOVE. If the filesystem does not support atomic moves (e.g. some network mounts, overlay quirks), publishing cannot be done safely and the loader throws rather than risk a partially visible library.","triggerScenarios":"Cache directory resides on a filesystem rejecting ATOMIC_MOVE: NFS/SMB/CIFS mounts, some container volume mounts, or cross-device move attempts.","commonSituations":"Building/running in Docker with the Maven/Gradle cache on a network volume; CI agents with workspaces on NFS; pointing the runtime cache at a mounted share.","solutions":["Move the runtime cache directory to a local filesystem path (e.g. /tmp or a local disk).","Provide a custom AtomicPublisher that handles non-atomic moves with a lock/rename-into-place scheme.","Avoid sharing the cache directory across devices; keep temp file and target in the same volume.","Update the loader to fall back to non-atomic move if your use case tolerates it."],"exampleFix":"// before\ncacheDir = \"/mnt/nfs/shared/copilot-runtime\";\n// after\ncacheDir = \"/var/tmp/copilot-runtime\"; // local filesystem supporting ATOMIC_MOVE","handlingStrategy":"fallback","validationCode":"try { Path t = Files.createTempFile(cacheDir, \"t\", \".tmp\"); Files.move(t, t.resolveSibling(\"m\"), StandardCopyOption.ATOMIC_MOVE); } catch (AtomicMoveNotSupportedException e) { /* switch cacheDir to local fs */ }","typeGuard":null,"tryCatchPattern":"try { lib = NativeRuntimeLoader.ensureRuntime(); } catch (IllegalStateException ex) { if (ex.getMessage().contains(\"atomic moves\")) { lib = NativeRuntimeLoader.ensureRuntime(localCacheDir()); } else throw ex; }","preventionTips":["Place runtime cache on local disk, not NFS/SMB mounts","Keep temp and target files in the same filesystem/volume","Test runtime extraction on the actual container/volume setup in CI"],"tags":["java","filesystem","atomic-move","native"],"backgroundTag":"unsupported-platform","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}