{"record":{"id":"5ba6e06bfbfa871b","repo":"nathanmarz/storm","slug":"this-state-is-read-only-and-does-not-support-updates","errorCode":null,"errorMessage":"This state is read-only and does not support updates","messagePattern":"This state is read-only and does not support updates","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"storm-core/src/jvm/storm/trident/state/ReadOnlyState.java","lineNumber":24,"sourceCode":" * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage storm.trident.state;\n\npublic class ReadOnlyState implements State {\n\n    @Override\n    public void beginCommit(Long txid) {\n        throw new UnsupportedOperationException(\"This state is read-only and does not support updates\");\n    }\n\n    @Override\n    public void commit(Long txid) {\n        throw new UnsupportedOperationException(\"This state is read-only and does not support updates\");\n    }    \n}\n","sourceCodeStart":6,"sourceCodeEnd":32,"githubUrl":"https://github.com/nathanmarz/storm/blob/cdb116e942666973bc4eaa0df098d5bab82739e7/storm-core/src/jvm/storm/trident/state/ReadOnlyState.java#L6-L32","documentation":"ReadOnlyState implements State but its beginCommit always throws UnsupportedOperationException because read-only states (backed by e.g. static data or DRPC queries) cannot participate in transactional writes.","triggerScenarios":"A Trident topology writes (state query/ partitionPersist/ persistentAggregate) to a state factory that returns a ReadOnlyState, causing beginCommit at batch start.","commonSituations":"Accidentally wiring a topology to a read-only state (e.g. a cached/lookup state) in a stream that aggregates or persists; copy-pasting a read-only state factory into a write path.","solutions":["Switch the stream to a writable state implementation (e.g. MemoryMapState, Redis/HBase-backed MapState)","Remove the persist/aggregate operation from the read-only branch of the topology","Wrap reads only via stateQuery and perform writes on a separate writable state"],"exampleFix":"// before\nTridentState state = topology.newStream(\"s\", spout)\n    .groupBy(fields)\n    .persistentAggregate(readOnlyStateFactory, new Count(), new Fields(\"count\"));\n// after\nTridentState state = topology.newStream(\"s\", spout)\n    .groupBy(fields)\n    .persistentAggregate(MemoryMapState.Factory(), new Count(), new Fields(\"count\"));","handlingStrategy":"validation","validationCode":"if (stateFactory instanceof ReadOnlyState || state instanceof ReadOnlyState) {\n  throw new IllegalArgumentException(\"Cannot persist to read-only state\");\n}","typeGuard":"boolean isWritable(State s) { return !(s instanceof ReadOnlyState); }","tryCatchPattern":"try {\n  state.beginCommit(txid);\n} catch (UnsupportedOperationException e) {\n  LOG.error(\"Attempted write to read-only state; fix topology wiring\", e);\n}","preventionTips":["Use stateQuery only for read-only states","Keep read-only and writable state factories in clearly named classes","Review topology wiring: persistentAggregate/partitionPersist require writable states"],"tags":["storm","trident","state","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"cdb116e942666973bc4eaa0df098d5bab82739e7","analyzedAt":"2026-09-12T14:30:00.714Z","contentChangedAt":"2026-09-12T14:30:00.714Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}