oracle/graal · error · UnsupportedOperationException
link option: {}
Error message
link option: {} What it means
Thrown by TrufflePath.followLinks when a LinkOption other than LinkOption.NOFOLLOW_LINKS is passed. LinkOption is a final enum-like class with exactly one constant, so in practice this fires only for a hand-rolled LinkOption subclass or a LinkOption loaded by a different class loader whose equals() fails against the constant. toRealPath(...) is the API that routes through this check.
Source
Thrown at espresso/src/com.oracle.truffle.espresso.io/src/sun/nio/fs/TrufflePath.java:183
@Override
public URI toUri() {
return URI.create(toURI0());
}
@Override
public Path toAbsolutePath() {
return new TrufflePath(getTruffleFileSystem(), toAbsolutePath0());
}
static boolean followLinks(LinkOption... options) {
if (options != null && options.length > 0) {
for (LinkOption option : options) {
Objects.requireNonNull(option);
if (option == LinkOption.NOFOLLOW_LINKS) {
return false;
} else {
throw new UnsupportedOperationException("link option: " + option);
}
}
}
return true;
}
@Override
public Path toRealPath(LinkOption... options) throws IOException {
return new TrufflePath(getTruffleFileSystem(), toRealPath0(followLinks(options)));
}
@Override
public WatchKey register(WatchService watcher, WatchEvent.Kind<?>[] events, WatchEvent.Modifier... modifiers) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public int compareTo(Path other) {View on GitHub (pinned to a66e9ccd1d)
Solutions
- Pass only LinkOption.NOFOLLOW_LINKS or an empty varargs array
- Remove custom LinkOption subclasses from your API and model extra flags separately
- Check for shadowed java.nio.file classes on the guest classpath
Example fix
// before path.toRealPath(myCustomNofollow); // after path.toRealPath(LinkOption.NOFOLLOW_LINKS);
Defensive patterns
Strategy: type-guard
Validate before calling
for (LinkOption o : options) {
if (o != LinkOption.NOFOLLOW_LINKS) throw new UnsupportedOperationException("link option: " + o);
} Type guard
static boolean isSupportedLinkOption(LinkOption... options) {
for (LinkOption o : options) {
if (o != LinkOption.NOFOLLOW_LINKS) return false;
}
return true;
} Prevention
- Pass LinkOption.NOFOLLOW_LINKS or nothing; never subclass LinkOption
- Avoid classpath shadowing of java.nio.file types in guest applications
When it happens
Trigger: Calling path.toRealPath(customLinkOption) with a non-constant LinkOption instance, or running with a shadowed java.nio.file.LinkOption class so option == LinkOption.NOFOLLOW_LINKS fails identity comparison.
Common situations: Framework code that subclasses LinkOption to smuggle extra flags; classpath/module-path shadowing of java.nio in the Espresso guest; version-skewed guest JDK builds.
Related errors
- Path not associated with default file system.
- Path component is undefined
- Path component should be '/'
- Query component present
- Fragment component present
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/2abd1a88b8e7fa07.
Report an issue: GitHub.