oracle/graal · error · IOException
Registration is not a singleton
Error message
Registration is not a singleton
What it means
IOException thrown by BinaryReplayCodec.ReadState.singletonProxy when the stream requests a singleton proxy for a registration whose Registration is not marked singleton. The decoder distinguishes singleton types (one shared proxy) from instance types (per-id proxies); a non-singleton registration at a singleton reference site means the stream's shape disagrees with the current declarations — corruption or version mismatch.
Source
Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/BinaryReplayCodec.java:288
private void defineMethod(int index, CompilationProxy.SymbolicMethod method) throws IOException {
if (index != methodTable.size()) {
throw new IOException("Invalid replay symbolic method definition index " + index);
}
methodTable.add(method);
}
private CompilerInterfaceDeclarations.Registration registrationAt(int index) throws IOException {
if (index < 0 || index >= registrations.length) {
throw new IOException("Invalid replay registration index " + index);
}
return registrations[index];
}
private Object singletonProxy(int registrationIndex) throws IOException {
CompilerInterfaceDeclarations.Registration registration = registrationAt(registrationIndex);
if (!registration.singleton()) {
throw new IOException("Registration " + registration.clazz().getName() + " is not a singleton");
}
Object proxy = singletonProxies[registrationIndex];
if (proxy == null) {
proxy = proxyFactory.createProxy(registration);
singletonProxies[registrationIndex] = proxy;
}
return proxy;
}
private Object instanceProxy(int registrationIndex, int id) throws IOException {
CompilerInterfaceDeclarations.Registration registration = registrationAt(registrationIndex);
if (registration.singleton()) {
throw new IOException("Registration " + registration.clazz().getName() + " is a singleton");
}
EconomicMap<Integer, Object> proxies = instanceProxies[registrationIndex];
if (proxies == null) {
proxies = EconomicMap.create();
instanceProxies[registrationIndex] = proxies;View on GitHub (pinned to a66e9ccd1d)
Solutions
- Regenerate the replay file with the same compiler build used for replay.
- Verify the file's integrity and retry.
- Treat replay data as build-local: never share across revisions.
Defensive patterns
Strategy: validation
Try / catch
try {
replayCodec.decode(input);
} catch (IOException e) {
if (e.getMessage().contains("is not a singleton")) {
// singleton markings differ between builds: regenerate replay data
}
throw e;
} Prevention
- Re-record replay files whenever compiler-interface singleton annotations change.
- Validate replay provenance (build id) before decoding.
When it happens
Trigger: A SINGLETON_PROXY record indexes a registration whose singleton() flag is false in the running build — e.g. the producing build treated the type as a singleton while the consumer does not, or bytes were shuffled.
Common situations: Cross-build replay after compiler-interface annotations changed (singleton added/removed); corrupted replay artifacts.
Related errors
- Invalid replay registration index
- Registration is a singleton
- Invalid replay string table index
- Invalid replay string definition index
- Invalid replay symbolic method index
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/24adec14aa7c53d9.
Report an issue: GitHub.