{"record":{"id":"d921575f880ce8bc","repo":"redis/redis-py","slug":"nx-and-xx-are-mutually-exclusive-use-one-the-oth","errorCode":null,"errorMessage":"nx and xx are mutually exclusive: use one, the other or neither - but not both","messagePattern":"nx and xx are mutually exclusive: use one, the other or neither - but not both","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"redis/commands/json/commands.py","lineNumber":519,"sourceCode":"        with utf-8.\n        ``fpha`` if set, forces Redis to use the specified floating-point type\n        for storing all FP homogeneous arrays in ``obj``.\n        Accepts a :class:`FPHAType` enum value or a string\n        (``\"BF16\"``, ``\"FP16\"``, ``\"FP32\"``, ``\"FP64\"``).\n\n        For the purpose of using this within a pipeline, this command is also\n        aliased to JSON.SET.\n\n        For more information see `JSON.SET <https://redis.io/commands/json.set>`_.\n        \"\"\"\n        if decode_keys:\n            obj = decode_dict_keys(obj)\n\n        pieces = [name, str(path), self._encode(obj)]\n\n        # Handle existential modifiers\n        if nx and xx:\n            raise Exception(\n                \"nx and xx are mutually exclusive: use one, the \"\n                \"other or neither - but not both\"\n            )\n        elif nx:\n            pieces.append(\"NX\")\n        elif xx:\n            pieces.append(\"XX\")\n\n        if fpha is not None:\n            pieces.extend([\"FPHA\", FPHAType.from_value(fpha).value])\n\n        return self.execute_command(\"JSON.SET\", *pieces)\n\n    @overload\n    def mset(\n        self: SyncClientProtocol, triplets: list[tuple[str, str, JsonType]]\n    ) -> bool: ...\n","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/commands/json/commands.py#L501-L537","documentation":"Raised by JSON SET (redis/commands/json/commands.py:519) as a plain Exception (not DataError - inconsistent with the rest of the module) when both nx=True and xx=True. NX means set only if the key/path does not exist; XX means set only if it exists - they are logically contradictory so the library rejects the combination before sending JSON.SET.","triggerScenarios":"Calling client.json().set(key, path, obj, nx=True, xx=True). Any code path that sets both flags True (e.g. building kwargs dynamically and both end up set).","commonSituations":"Conditional logic that flips both flags, copy-paste from two examples, or a config object that enables both modes. Because this is a bare Exception (not DataError), a broad `except DataError` will NOT catch it.","solutions":["Pass at most one of nx or xx (or neither for unconditional set).","Decide the intended semantics: nx = create-only, xx = update-only.","If building flags dynamically, assert not (nx and xx) before the call."],"exampleFix":"# before\nclient.json().set('doc', '$', obj, nx=create_only, xx=update_only)\n# after\nif create_only and update_only:\n    raise ValueError('cannot be both create-only and update-only')\nclient.json().set('doc', '$', obj, nx=create_only, xx=update_only)","handlingStrategy":"validation","validationCode":"def json_set_flags(nx, xx):\n    if nx and xx:\n        raise ValueError('nx and xx are mutually exclusive')\n    return nx, xx","typeGuard":"def valid_json_set_mode(nx, xx) -> bool:\n    return not (nx and xx)","tryCatchPattern":"# NOTE: this raises a bare Exception, NOT DataError - catch broadly\ntry:\n    client.json().set('k', '$', obj, nx=nx, xx=xx)\nexcept Exception as e:\n    if 'mutually exclusive' in str(e):\n        # pick one mode explicitly\n        client.json().set('k', '$', obj, nx=True)\n    else:\n        raise","preventionTips":["Never set both nx and xx; assert not (nx and xx) before the call.","Decide create-only (nx) vs update-only (xx) at the call site.","Remember this is a bare Exception - a DataError-only handler will miss it."],"tags":["json","jsonset","argument-validation","mutually-exclusive","exception"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}