{"record":{"id":"5b9e652f1e388cc2","repo":"pathwaycom/pathway","slug":"trying-to-delete-a-row-in-type-self-but-deletio","errorCode":null,"errorMessage":"Trying to delete a row in {type(self)} but deletions_enabled is set to False.","messagePattern":"Trying to delete a row in (.+?) but deletions_enabled is set to False\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/io/python/__init__.py","lineNumber":286,"sourceCode":"        if self._session_type == SessionType.NATIVE:\n            self._buffer.put((PythonConnectorEventType.INSERT, key, values))\n        elif self._session_type == SessionType.UPSERT:\n            if not self._deletions_enabled:\n                raise ValueError(\n                    f\"Trying to modify a row in {type(self)} but deletions_enabled is set to False.\"\n                )\n            self._buffer.put((PythonConnectorEventType.INSERT, key, values))\n        else:\n            raise NotImplementedError(f\"session type {self._session_type} not handled\")\n\n    def _remove(\n        self, key: Pointer, message: bytes, metadata: bytes | None = None\n    ) -> None:\n        self._remove_inner(key, self._get_values_dict(message, metadata))\n\n    def _remove_inner(self, key: Pointer | None, values: dict[str, Any]) -> None:\n        if not self._deletions_enabled:\n            raise ValueError(\n                f\"Trying to delete a row in {type(self)} but deletions_enabled is set to False.\"\n            )\n        self._buffer.put((PythonConnectorEventType.DELETE, key, values))\n\n    def _read(self) -> Any:\n        \"\"\"Allows to retrieve data from a buffer.\n\n        Should not be called directly.\n        \"\"\"\n        return self._buffer.get()\n\n    def _is_internal(self) -> bool:\n        \"\"\"\n        The Python connector is internal in case it is used to implement an internal\n        The Pathway Live Data Framework feature rather than to read the data from an external source.\n\n        We need this distinction, because internal usages don't read user data and\n        aren't a part of the external perimeter, which is currently persisted. Therefore","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/io/python/__init__.py#L268-L304","documentation":"Raised by Pathway's Python input connector when a custom ConnectorSubject calls subject.remove(key, ...) while the connector was created with deletions_enabled=False. Deletions are opt-in for python connectors, so emitting a retract on an append-only connector is rejected at the source rather than dropped silently, which would desynchronize downstream state from reality.","triggerScenarios":"A ConnectorSubject.run() that calls self.remove(key, payload) for tombstoned events, while pw.io.python.read(subject, ..., deletions_enabled=False) was configured (e.g. to reduce memory usage in static workloads).","commonSituations":"Reading a changelog/DEBEZIUM-style feed where deletes appear, with deletions_enabled=False chosen for performance; upgrading an append-only prototype to a real source that now sends tombstones without flipping the flag back.","solutions":["Pass deletions_enabled=True to pw.io.python.read so remove() is honored.","If deletions must stay disabled, filter tombstones inside the subject's run() and never call remove().","For batch/static sources that finish and never retract, keep deletions_enabled=False and simply omit any delete emissions."],"exampleFix":"# before\ndef run(self):\n    for key, payload, deleted in feed:\n        if deleted:\n            self.remove(key, payload)  # not allowed: deletions disabled\npw.io.python.read(Subj(), schema=S, deletions_enabled=False)\n\n# after\npw.io.python.read(Subj(), schema=S)  # deletions_enabled=True","handlingStrategy":"validation","validationCode":"source_can_delete = True\npw.io.python.read(Subj(), schema=S, deletions_enabled=source_can_delete)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass deletions_enabled=True for changelog/tombstone-carrying feeds.","Filter tombstones inside subject.run() if deletions must stay disabled.","Re-check the flag whenever a source gains delete events."],"tags":["pathway","python-connector","deletions","runtime","api-misuse"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}