antlr/antlr4 · error · IllegalStateException
The object is read only.
Error message
The object is read only.
What it means
ATNDeserializationOptions becomes immutable after makeReadOnly(), and the static defaultOptions instance is created read-only. Any setter such as setVerifyATN or setGenerateRuleBypassTransitions throws IllegalStateException on that object. Mutable options must be a separately constructed instance.
Source
Thrown at runtime/Java/src/org/antlr/v4/runtime/atn/ATNDeserializationOptions.java:67
}
public final void setVerifyATN(boolean verifyATN) {
throwIfReadOnly();
this.verifyATN = verifyATN;
}
public final boolean isGenerateRuleBypassTransitions() {
return generateRuleBypassTransitions;
}
public final void setGenerateRuleBypassTransitions(boolean generateRuleBypassTransitions) {
throwIfReadOnly();
this.generateRuleBypassTransitions = generateRuleBypassTransitions;
}
protected void throwIfReadOnly() {
if (isReadOnly()) {
throw new IllegalStateException("The object is read only.");
}
}
}
View on GitHub (pinned to 7d5770395b)
Solutions
- Create new ATNDeserializationOptions() for mutable settings.
- Use the copy constructor when deriving from existing options; it copies settings but not readOnly.
- Call makeReadOnly() only after all setters have run.
- Never mutate getDefaultOptions(); pass it to ATNDeserializer unchanged.
Example fix
// before ATNDeserializationOptions options = ATNDeserializationOptions.getDefaultOptions(); options.setVerifyATN(false); // default instance is readonly // after ATNDeserializationOptions options = new ATNDeserializationOptions(); options.setVerifyATN(false); ATN atn = new ATNDeserializer(options).deserialize(serializedAtn);
Defensive patterns
Strategy: validation
Validate before calling
static ATNDeserializationOptions mutableCopy(ATNDeserializationOptions source) {
ATNDeserializationOptions copy = new ATNDeserializationOptions(source);
if (copy.isReadOnly()) {
throw new IllegalStateException("Copy unexpectedly readonly");
}
return copy;
} Try / catch
try {
options.setVerifyATN(false);
} catch (IllegalStateException e) {
options = new ATNDeserializationOptions();
options.setVerifyATN(false);
} Prevention
- Never mutate getDefaultOptions().
- Create options locally per deserializer configuration.
- Seal options only after configuration is complete.
When it happens
Trigger: Calling ATNDeserializationOptions.getDefaultOptions().setVerifyATN(false); calling any setter after explicitly invoking makeReadOnly(); or caching one options object, sealing it, and later reconfiguring it.
Common situations: Trying to tune the global default deserialization behavior, sharing an options singleton across setup code, and custom ATN deserializers.
Related errors
- This set is readonly
- This method is not implemented for readonly sets.
- Invalid state number.
- Could not deserialize ATN with version %d (expected %d).
- Couldn't identify final state of the precedence rule prefix
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/ae22851ef19382a9.
Report an issue: GitHub.