{"record":{"id":"6bc0ce4b1493452a","repo":"prestodb/presto","slug":"read-only-violation","errorCode":"READ_ONLY_VIOLATION","errorMessage":"Cannot execute write in a read-only transaction","messagePattern":"Cannot execute write in a read-only transaction","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/transaction/InMemoryTransactionManager.java","lineNumber":586,"sourceCode":"        }\n\n        private ConnectorTransactionHandle beginTransaction(Connector connector)\n        {\n            if (connector instanceof InternalConnector) {\n                return ((InternalConnector) connector).beginTransaction(transactionId, isolationLevel, readOnly);\n            }\n            else {\n                return connector.beginTransaction(isolationLevel, autoCommitContext, readOnly);\n            }\n        }\n\n        public synchronized void checkConnectorWrite(ConnectorId connectorId)\n        {\n            checkOpenTransaction();\n            ConnectorTransactionMetadata transactionMetadata = connectorIdToMetadata.get(connectorId);\n            checkArgument(transactionMetadata != null, \"Cannot record write for connector not part of transaction\");\n            if (readOnly) {\n                throw new PrestoException(READ_ONLY_VIOLATION, \"Cannot execute write in a read-only transaction\");\n            }\n            if (!writtenConnectorId.compareAndSet(null, connectorId) && !writtenConnectorId.get().equals(connectorId)) {\n                throw new PrestoException(\n                        MULTI_CATALOG_WRITE_CONFLICT,\n                        format(\n                                \"Multi-catalog writes not supported in a single transaction. Attempt write to catalog %s, but already wrote to catalog %s\",\n                                connectorId,\n                                writtenConnectorId.get()));\n            }\n            if (transactionMetadata.isSingleStatementWritesOnly() && !autoCommitContext) {\n                throw new PrestoException(AUTOCOMMIT_WRITE_CONFLICT, \"Catalog \" + connectorId + \" only supports writes using autocommit\");\n            }\n        }\n\n        public synchronized ListenableFuture<?> asyncCommit()\n        {\n            if (!completedSuccessfully.compareAndSet(null, true)) {\n                if (completedSuccessfully.get()) {","sourceCodeStart":568,"sourceCodeEnd":604,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/transaction/InMemoryTransactionManager.java#L568-L604","documentation":"Thrown by TransactionMetadata.checkConnectorWrite when a connector attempts to record a write (checkConnectorWrite) while the enclosing Presto transaction was started read-only. Read-only transactions disallow all data/schema modifications; the write must occur in a read-write transaction.","triggerScenarios":"A connector calls checkConnectorWrite(connectorId) during a transaction created with readOnly=true (e.g. START TRANSACTION READ ONLY, or a session defaulting to read-only), and the connector attempts an INSERT/UPDATE/DDL through that transaction.","commonSituations":"Session was opened READ ONLY but the client later runs a write statement; JDBC/CLI default transaction mode is read-only while an application assumes read-write; a metadata plugin records a write during a read-only transaction.","solutions":["Start the transaction as read-write: START TRANSACTION READ WRITE (or beginTransaction(false) when creating the transaction programmatically).","Remove the READ ONLY qualifier / fix the client session properties that force read-only transactions.","If the write is accidental, move it outside the transaction or into autocommit mode.","Audit connector code so writes are only attempted when the transaction is known to be writable."],"exampleFix":"// before\nSTART TRANSACTION READ ONLY;\nINSERT INTO t VALUES (1);\n\n// after\nSTART TRANSACTION READ WRITE;\nINSERT INTO t VALUES (1);","handlingStrategy":"validation","validationCode":"-- Before running writes, ensure the transaction is read-write\nSHOW TRANSACTION;\n-- or in the client: begin a read-write transaction\nSTART TRANSACTION READ WRITE;","typeGuard":"boolean canWrite(TransactionManager tm, TransactionId id) {\n    return !tm.getTransactionInfo(id).isReadOnly();\n}","tryCatchPattern":"try {\n    connectorHandle.beginQuery(txH, metadata);\n} catch (PrestoException e) {\n    if (e.getErrorCode().getCode() == StandardErrorCode.READ_ONLY_VIOLATION.toErrorCode().getCode()) {\n        transactionManager.abortTransaction(txId);\n        txId = transactionManager.beginTransaction(false); // read-write\n    } else {\n        throw e;\n    }\n}","preventionTips":["Do not add READ ONLY to transactions that may perform writes.","Check session/connector defaults that force read-only transaction mode.","Separate read-only analytical transactions from write workloads.","Inspect SHOW TRANSACTION or TransactionInfo.isReadOnly before issuing DML/DDL."],"tags":["transaction","read-only","presto"],"backgroundTag":"read-only-transaction-violation","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}