{"record":{"id":"f3bf6e86d5358cff","repo":"oracle/graal","slug":"open-option","errorCode":null,"errorMessage":"open option: {}","messagePattern":"open option: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"espresso/src/com.oracle.truffle.espresso.io/src/sun/nio/fs/TruffleFileSystemProvider.java","lineNumber":224,"sourceCode":"    private static int copyOptionsToMask(CopyOption... options) {\n        int mask = 0;\n        for (CopyOption option : options) {\n            int index = SUPPORTED_COPY_OPTIONS.indexOf(option);\n            if (index < 0) {\n                throw new UnsupportedOperationException(\"copy option: \" + option);\n            }\n            assert index < 32;\n            mask |= 1 << index;\n        }\n        return mask;\n    }\n\n    private static int openOptionsToMask(Set<? extends OpenOption> options) {\n        int mask = 0;\n        for (OpenOption option : options) {\n            int index = SUPPORTED_OPEN_OPTIONS.indexOf(option);\n            if (index < 0) {\n                throw new UnsupportedOperationException(\"open option: \" + option);\n            }\n            mask |= 1 << index;\n        }\n        return mask;\n    }\n\n    @Override\n    public void copy(Path source, Path target, CopyOption... options) throws IOException {\n        copy0(TrufflePath.toTrufflePath(source), TrufflePath.toTrufflePath(target), copyOptionsToMask(options));\n    }\n\n    @Override\n    public void move(Path source, Path target, CopyOption... options) throws IOException {\n        move0(TrufflePath.toTrufflePath(source), TrufflePath.toTrufflePath(target), copyOptionsToMask(options));\n    }\n\n    @Override\n    public boolean isSameFile(Path path, Path path2) throws IOException {","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso/src/com.oracle.truffle.espresso.io/src/sun/nio/fs/TruffleFileSystemProvider.java#L206-L242","documentation":"Thrown by TruffleFileSystemProvider.openOptionsToMask when an OpenOption in the set is not in SUPPORTED_OPEN_OPTIONS. The provider supports READ, WRITE, APPEND, TRUNCATE_EXISTING, CREATE, CREATE_NEW, DELETE_ON_CLOSE, SPARSE, SYNC, DSYNC, and LinkOption.NOFOLLOW_LINKS; the list must stay in sync with the guest-side Target_*_TruffleFileSystemProvider. Anything else (a custom OpenOption) has no bitmask slot.","triggerScenarios":"Files.newByteChannel/newFileChannel/newOutputStream/newInputStream on a TrufflePath with a user-defined OpenOption implementation, since all eleven standard StandardOpenOption values are supported.","commonSituations":"Libraries that define their own OpenOption (e.g. for direct-I/O or compression hints) and pass it through Files.*; code migrating from another provider that accepts extended options.","solutions":["Remove the custom OpenOption from the set before opening the channel","Check option instanceof StandardOpenOption or LinkOption.NOFOLLOW_LINKS in generic wrappers and drop unknown ones","For unsupported behavior (e.g. custom buffering), wrap the resulting channel instead of using an option"],"exampleFix":"// before\nFiles.newByteChannel(path, Set.of(CREATE, WRITE, new DirectIoOption()));\n\n// after\nFiles.newByteChannel(path, Set.of(StandardOpenOption.CREATE, StandardOpenOption.WRITE));","handlingStrategy":"validation","validationCode":"private static final Set<OpenOption> TRUFFLE_OPEN_OPTIONS = Set.of(\n    StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.APPEND,\n    StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE, StandardOpenOption.CREATE_NEW,\n    StandardOpenOption.DELETE_ON_CLOSE, StandardOpenOption.SPARSE, StandardOpenOption.SYNC,\n    StandardOpenOption.DSYNC, LinkOption.NOFOLLOW_LINKS);\noptions.removeIf(o -> !TRUFFLE_OPEN_OPTIONS.contains(o));","typeGuard":null,"tryCatchPattern":"catch (UnsupportedOperationException e) when message starts with 'open option': retry with options filtered to the eleven supported constants.","preventionTips":["Do not invent custom OpenOption implementations for code that must run on the Truffle FS","Keep option filtering in one wrapper around Files.newByteChannel"],"tags":["espresso","nio","open-options","file-system","truffle"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}