{"record":{"id":"3d29f8626e884951","repo":"apache/beam","slug":"no-or-more-than-one-write-mutation-operation-provided-s-s","errorCode":null,"errorMessage":"No or more than one write mutation operation provided: <%s: %s>","messagePattern":"No or more than one write mutation operation provided: <(.+?): (.+?)>","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/gcp/experimental/spannerio.py","lineNumber":999,"sourceCode":"        lists is equivalent to sending multiple Mutations, each containing one\n        `values` entry and repeating table and columns.\n      keyset: (Optional) The primary keys of the rows within table to delete.\n        Delete is idempotent. The transaction will succeed even if some or\n        all rows do not exist.\n    \"\"\"\n    self._columns = columns\n    self._values = values\n    self._keyset = keyset\n\n    self._insert = insert\n    self._update = update\n    self._insert_or_update = insert_or_update\n    self._replace = replace\n    self._delete = delete\n\n    if sum([1 for x in [self._insert, self._update, self._insert_or_update,\n                        self._replace, self._delete] if x is not None]) != 1:\n      raise ValueError(\n          \"No or more than one write mutation operation \"\n          \"provided: <%s: %s>\" % (self.__class__.__name__, str(self.__dict__)))\n\n  def __call__(self, *args, **kwargs):\n    if self._insert is not None:\n      return WriteMutation.insert(\n          table=self._insert, columns=self._columns, values=self._values)\n    elif self._update is not None:\n      return WriteMutation.update(\n          table=self._update, columns=self._columns, values=self._values)\n    elif self._insert_or_update is not None:\n      return WriteMutation.insert_or_update(\n          table=self._insert_or_update,\n          columns=self._columns,\n          values=self._values)\n    elif self._replace is not None:\n      return WriteMutation.replace(\n          table=self._replace, columns=self._columns, values=self._values)","sourceCodeStart":981,"sourceCodeEnd":1017,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/gcp/experimental/spannerio.py#L981-L1017","documentation":"WriteMutation is a wrapper for exactly one Spanner write mutation (insert, update, insert_or_update, replace, or delete). Its constructor raises this ValueError if zero or more than one of these mutation collections is provided, because a mutation must represent a single operation kind.","triggerScenarios":"Calling WriteMutation.insert(...) plus another setter like WriteMutation.delete(...) in the same constructor; or creating a WriteMutation with all-None mutation args (e.g. WriteMutation() with keyword args that resolve to None).","commonSituations":"Programmatically building mutations where several candidate mutation lists default to non-None empty values or where a variable may be None and more than one gets passed; typos passing two operation kinds at once.","solutions":["Ensure exactly one of insert/update/insert_or_update/replace/delete is non-None in the constructor call.","If the operation is dynamic, compute the correct WriteMutation class method before constructing.","Wrap multiple operations in a MutationGroup with separate WriteMutation instances instead."],"exampleFix":"# before\nWriteMutation.insert(table, entities, delete=delete_ops)\n# after\nWriteMutation.insert(table, entities)","handlingStrategy":"validation","validationCode":"def make_write_mutation(operation, table, rows):\n    factories = {'insert': 'insert', 'update': 'update',\n                 'insert_or_update': 'insert_or_update',\n                 'replace': 'replace', 'delete': 'delete'}\n    assert operation in factories and operation is not None\n    return getattr(WriteMutation, factories[operation])(table, rows)","typeGuard":null,"tryCatchPattern":"try:\n    mutation = WriteMutation.insert(t, rows, **extra)\nexcept ValueError as e:\n    logging.error('WriteMutation must wrap exactly one operation: %s', e)\n    raise","preventionTips":["Pass only one mutation kind per WriteMutation call","Use factory methods (insert/update/delete/...) rather than raw constructor kwargs","Combine multiple operations with MutationGroup of separate WriteMutation objects"],"tags":["apache-beam","google-cloud-spanner","mutation","valueerror"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}