How to Fix TypeError: descriptors cannot not be created directly

TypeError: descriptors cannot not be created directly error typically occurs when you encounter the incompatibility of the protobuf package. This incompatibility can be direct or because of any other Python module.

Here are four ways to fix this error:

  1. Downgrade protobuf to 3.20.x version
  2. Setting the PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION environment variable
  3. Use the virtual environment
  4. Using the .proto file

Flowchart

Diagram of How to Fix TypeError: descriptors cannot not be created directly

Cause of this error

The main cause of this error is that new changes have been introduced in protobuf 4.0.0. You can find more details on this link: https://developers.google.com/protocol-buffers/docs/news/2022-05-06#python-updates

How to fix it?

Solution 1: Downgrade protobuf to 3.20.x version

There are multiple releases of protobuf in 4. x.x, but the most stable version was 3.30.x series. So if you are currently on protobuf 4. x.x series, Please downgrade to 3.20.x series.

pip install protobuf==3.20.*

# OR

pip install 'protobuf<=3.20.1' --force-reinstall

Solution 2: Setting the PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION environment variable

You can “set the environment variable” like this:

export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python

Solution 3: Use the Virtual Environment

In some cases, if your package (such as wandb, googleapis-common-protos, etc.) uses an old version of protobuf and your environment has a new one or vice versa, you may face compatibility issues.

If you are using multiple projects at the same Python version, Suppose you upgrade protobuf or any other module internally invoked by another package.

Solution 4: Using the .proto file

If there is a problem with the .proto file, you can define your messages in a .proto file and use the Protocol Buffers compiler to generate the descriptor objects.

See the sample code of the .proto file.

syntax = "proto3";

message MyMessage {
  int32 id = 1;
  string name = 2;
}

The next step is to use the Protocol Buffers compiler to generate the descriptors for the messages defined in the .proto file.

protoc --python_out=./ my_messages.proto

After generating the descriptors, you can use them in your code to encode and decode messages.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.