{"record":{"id":"82e83ef83f9989aa","repo":"jax-ml/jax","slug":"buffer-dlpack-with-copy-true-is-not-supported","errorCode":null,"errorMessage":"Buffer.__dlpack__ with copy=True is not supported.","messagePattern":"Buffer\\.__dlpack__ with copy=True is not supported\\.","errorType":"validation","errorClass":"nb::value_error","httpStatus":null,"severity":"error","filePath":"jaxlib/ffi.cc","lineNumber":461,"sourceCode":"          throw nb::value_error(\n              \"dtype parameter is not supported by Buffer.__array__.\");\n        }\n        if (!copy.is_none() && nb::cast<bool>(copy)) {\n          throw nb::value_error(\n              \"Buffer.__array__ with copy=True is not supported.\");\n        }\n        return xla::ValueOrThrow(self.NumpyArray());\n      },\n      nb::arg(\"dtype\") = nb::none(), nb::arg(\"copy\") = nb::none());\n  buffer.def_prop_ro(\n      \"__cuda_array_interface__\",\n      xla::ValueOrThrowWrapper(&PyFfiAnyBuffer::CudaArrayInterface));\n  buffer.def(\n      \"__dlpack__\",\n      [](PyFfiAnyBuffer self, nb::object stream, nb::object max_version,\n         nb::object dl_device, nb::object copy) {\n        if (!copy.is_none() && nb::cast<bool>(copy)) {\n          throw nb::value_error(\n              \"Buffer.__dlpack__ with copy=True is not supported.\");\n        }\n\n        // Fall back on the non-versioned API if unsupported by the requested\n        // max_version.\n        nb::tuple max_version_tuple;\n        int64_t max_version_major;\n        if (!nb::try_cast<nb::tuple>(max_version, max_version_tuple) ||\n            max_version_tuple.size() < 2 ||\n            !nb::try_cast<int64_t>(max_version_tuple[0], max_version_major) ||\n            max_version_major < 1) {\n          return xla::ValueOrThrow(self.DLPack());\n        }\n\n        // TODO(danfm): Handle other optional inputs.\n        return xla::ValueOrThrow(self.DLPackVersioned());\n      },\n      nb::arg(\"stream\") = nb::none(), nb::arg(\"max_version\") = nb::none(),","sourceCodeStart":443,"sourceCodeEnd":479,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jaxlib/ffi.cc#L443-L479","documentation":"The FFI Buffer's __dlpack__ exports the buffer zero-copy; copy=True is not implemented and is explicitly rejected so callers don't assume a copied tensor.","triggerScenarios":"buffer.__dlpack__(copy=True) on an xla.ffi Buffer, typically from torch.from_dlpack or generic dlpack consumers that pass copy under dlpack>=1.0 protocol.","commonSituations":"Interop code that unconditionally passes copy=True to __dlpack__ on NumPy 2 / DLPack 1.0 consumers.","solutions":["Omit copy (get the zero-copy export) and let the consumer copy if needed","Patch the consumer to pass copy=False/None","Ensure the buffer outlives the consumer tensor to keep zero-copy safe"],"exampleFix":"# before\nconsumer.from_dlpack(buf.__dlpack__(copy=True))\n# after\nconsumer.from_dlpack(buf.__dlpack__())","handlingStrategy":"validation","validationCode":"capsule = buf.__dlpack__()  # no copy kwarg","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the source buffer alive while the consumer tensor exists","Never pass copy=True to FFI Buffer __dlpack__"],"tags":["jax","ffi","dlpack","copy"],"backgroundTag":"unsupported-argument-value","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}