{"record":{"id":"3c528027340815f7","repo":"jax-ml/jax","slug":"c-api-argument-to-load-pjrt-plugin-is-not-a-pjrt-c","errorCode":null,"errorMessage":"c_api argument to load_pjrt_plugin is not a pjrt_c_api capsule.","messagePattern":"c_api argument to load_pjrt_plugin is not a pjrt_c_api capsule\\.","errorType":"validation","errorClass":"nb::value_error","httpStatus":null,"severity":"error","filePath":"jaxlib/jax.cc","lineNumber":522,"sourceCode":"      nb::arg(\"num_devices\").none() = std::nullopt,\n      nb::arg(\"get_local_topology_timeout_minutes\").none() = std::nullopt,\n      nb::arg(\"get_global_topology_timeout_minutes\").none() = std::nullopt,\n      nb::arg(\"transfer_server_factory\").none() = std::nullopt);\n  m.def(\"pjrt_plugin_loaded\", [](std::string platform_name) -> bool {\n    absl::StatusOr<const PJRT_Api*> pjrt_api = pjrt::PjrtApi(platform_name);\n    return pjrt_api.ok();\n  });\n  m.def(\n      \"load_pjrt_plugin\",\n      [](std::string platform_name, std::optional<std::string> library_path,\n         std::optional<nb::capsule> c_api) -> nb::capsule {\n        if (library_path.has_value()) {\n          const PJRT_Api* api = xla::ValueOrThrow(\n              pjrt::LoadPjrtPlugin(platform_name, *library_path));\n          return nb::capsule(absl::bit_cast<void*>(api), \"pjrt_c_api\");\n        }\n        if (std::string_view(c_api->name()) != \"pjrt_c_api\") {\n          throw nb::value_error(\n              \"c_api argument to load_pjrt_plugin is not a pjrt_c_api \"\n              \"capsule.\");\n        }\n        xla::ThrowIfError(pjrt::SetPjrtApi(\n            platform_name, static_cast<const PJRT_Api*>(c_api->data())));\n        return *c_api;\n      },\n      nb::arg(\"platform_name\"), nb::arg(\"library_path\").none() = std::nullopt,\n      nb::arg(\"c_api\").none() = std::nullopt);\n  m.def(\n      \"get_pjrt_plugin\",\n      [](std::string platform_name) -> nb::capsule {\n        const PJRT_Api* api = xla::ValueOrThrow(pjrt::PjrtApi(platform_name));\n        return nb::capsule(absl::bit_cast<void*>(api), \"pjrt_c_api\");\n      },\n      nb::arg(\"platform_name\"));\n  m.def(\"pjrt_plugin_initialized\", [](std::string platform_name) -> bool {\n    return xla::ValueOrThrow(pjrt::IsPjrtPluginInitialized(platform_name));","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jaxlib/jax.cc#L504-L540","documentation":"When load_pjrt_plugin is called with an existing c_api capsule (rather than a library path), that capsule must be named 'pjrt_c_api' so jaxlib can trust its payload is a PJRT_Api*.","triggerScenarios":"jaxlib.load_pjrt_plugin(platform, c_api=cap) where cap came from anything other than a prior load_pjrt_plugin result or a properly named capsule.","commonSituations":"Plugin bootstrap code that creates its own capsule with a different name, or passes a capsule that was consumed/renamed.","solutions":["Call load_pjrt_plugin(platform_name, library_path=...) to let jaxlib create the capsule","Pass the exact capsule previously returned by load_pjrt_plugin or get_backend_c_api"],"exampleFix":"# before\njaxlib.load_pjrt_plugin('mydev', c_api=mystery_capsule)\n# after\napi = jaxlib.load_pjrt_plugin('mydev', library_path='/path/libplugin.so')","handlingStrategy":"validation","validationCode":"assert c_api is None or getattr(c_api, 'name', lambda: None)() == 'pjrt_c_api'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use library_path mode when in doubt","Only forward capsules produced by load_pjrt_plugin"],"tags":["jax","pjrt","plugin","capsule","validation"],"backgroundTag":"invalid-capsule-argument","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}