{"record":{"id":"50db2070ef52a285","repo":"apache/cassandra","slug":"node-ops-is-a-write-only-table","errorCode":null,"errorMessage":"NODE_OPS + \" is a write-only table\"","messagePattern":"NODE_OPS \\+ \" is a write-only table\"","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/virtual/AccordDebugKeyspace.java","lineNumber":1950,"sourceCode":"            {\n                this.description = description;\n            }\n        }\n        private NodeOpsTable()\n        {\n            super(parse(VIRTUAL_ACCORD_DEBUG, NODE_OPS,\n                        \"Update Accord Node State\",\n                        \"CREATE TABLE %s (\\n\" +\n                        \"  node_id int,\\n\" +\n                        \"  op text,\" +\n                        \"  PRIMARY KEY (node_id)\" +\n                        ')', Int32Type.instance), FAIL, UNSORTED);\n        }\n\n        @Override\n        protected void collect(PartitionsCollector collector)\n        {\n            throw new UnsupportedOperationException(NODE_OPS + \" is a write-only table\");\n        }\n\n        @Override\n        protected void applyRowUpdate(Object[] partitionKeys, Object[] clusteringKeys, ColumnMetadata[] columns, Object[] values)\n        {\n            NodeId nodeId = new NodeId((Integer) partitionKeys[0]);\n            Set<NodeId> nodeIds = Collections.singleton(nodeId);\n            NodeOp op = tryParse(values[0], true, NodeOp.class, NodeOp::valueOf);\n\n            switch (op)\n            {\n                default: throw new UnhandledEnum(op);\n                case MARK_STALE:\n                    AccordOperations.instance.accordMarkStale(nodeIds);\n                    break;\n                case UNMARK_STALE:\n                    AccordOperations.instance.accordMarkRejoining(nodeIds);\n                    break;","sourceCodeStart":1932,"sourceCodeEnd":1968,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/virtual/AccordDebugKeyspace.java#L1932-L1968","documentation":"The `accord_node_ops` virtual table is write-only: it accepts INSERTs to enqueue node-level debug operations but implements no read path, so any SELECT throws UnsupportedOperationException from collect().","triggerScenarios":"Running a SELECT against system_views.accord_node_ops, e.g. `SELECT * FROM system_views.accord_node_ops;`, which calls the unimplemented collect(PartitionsCollector).","commonSituations":"Inspecting the table before writing an op; automation enumerating all virtual tables; confusing this op-queue table with the readable accord debug status tables.","solutions":["Do not SELECT from accord_node_ops; only INSERT rows to trigger node debug operations.","Observe operation results via the appropriate readable debug/status tables or node logs.","If a read view is required, add a separate readable virtual table upstream."],"exampleFix":"// before\nSELECT * FROM system_views.accord_node_ops;\n// after\nINSERT INTO system_views.accord_node_ops (node_id, op) VALUES (1, '<op>');","handlingStrategy":"validation","validationCode":"if (query.trim().toUpperCase().startsWith(\"SELECT\") && query.contains(\"accord_node_ops\"))\n    throw new IllegalArgumentException(\"accord_node_ops is write-only; do not SELECT from it\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat all accord_*_ops virtual tables as insert-only op queues.","Capture operation outcomes from logs or readable debug tables.","Exclude op tables from any generic virtual-table snapshot tooling."],"tags":["virtual-table","unsupported-read","accord-debug"],"backgroundTag":"unsupported-operation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}