`Transformer.to_json()` returns `None` for valid CRS pair
Code Sample, a copy-pastable example if possible
from pyproj import Transformer
t = Transformer.from_crs("EPSG:4258", "EPSG:32633")
print(t)
print(t.to_json())
print(t.to_json_dict())
unavailable until proj_trans is called
None
Traceback (most recent call last):
File "/data/src/test.py", line 6, in <module>
print(t.to_json_dict()) # TypeError: the JSON object must be str, bytes or bytearray, not NoneType
^^^^^^^^^^^^^^^^
File "/home/hdd/miniconda3/envs/py312/lib/python3.12/site-packages/pyproj/transformer.py", line 1157, in to_json_dict
return self._transformer.to_json_dict()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "pyproj/_crs.pyx", line 477, in pyproj._crs.Base.to_json_dict
File "/home/hdd/miniconda3/envs/py312/lib/python3.12/json/__init__.py", line 339, in loads
raise TypeError(f'the JSON object must be str, bytes or bytearray, '
TypeError: the JSON object must be str, bytes or bytearray, not NoneType
Problem description
Creating a Transformer via Transformer.from_crs("EPSG:4258", "EPSG:32633") yields an object whose to_json() method returns None. The docstring promise a JSON string, so downstream code that expects a str crashes (e.g., json.loads).
Expected Output
The return should be a valid json str.
Environment Information
- Output from:
pyproj -v
pyproj info:
pyproj: 3.7.2
PROJ (runtime): 9.5.1
PROJ (compiled): 9.5.1
data dir: /home/hdd/PBT-AgentSys/src/envs/pyproj_env/lib/python3.12/site-packages/pyproj/proj_dir/share/proj
user_data_dir: /home/.local/share/proj
PROJ DATA (recommended version): 1.20
PROJ Database: 1.4
EPSG Database: v11.022 [2024-11-05]
ESRI Database: ArcGIS Pro 3.4 [2024-11-04]
IGNF Database: 3.1.0 [2019-05-24]
System:
python: 3.12.12 | packaged by Anaconda, Inc. | (main, Oct 21 2025, 20:16:04) [GCC 11.2.0]
executable: /home/hdd/PBT-AgentSys/src/envs/pyproj_env/bin/python3
machine: Linux-5.15.0-139-generic-x86_64-with-glibc2.31
Python deps:
certifi: 2025.10.5
Cython: None
setuptools: None
pip: 25.0.1
Installation method
pip (inside a virtual environment)
from pyproj import Transformer
t = Transformer.from_crs("EPSG:4326", "EPSG:27700")
print(t.transform(-0.1278, 51.5074))
print(t.to_wkt()) # None <-- should be a WKT string
print(t.to_wkt(pretty=True)) # None <-- same issue
The same problem.
This is expected behavior rather than a bug. It's designed this way.
When you call Transformer.from_crs(), PROJ creates a "late-binding" transformer that doesn't immediately select a single transformation. Instead, it defers the selection until runtime when actual coordinates are provided, allowing PROJ to choose the best transformation based on the coordinate location.
The message "unavailable until proj_trans is called" indicates this - no specific transformation has been selected yet, so there's nothing concrete to serialize to JSON/WKT.
Workaround: Call transform() first, then use get_last_used_operation() to get the concrete operation:
from pyproj import Transformer
t = Transformer.from_crs("EPSG:4258", "EPSG:32632", always_xy=True)
# Trigger transformation selection
t.transform(10, 60)
# Now get the actual operation used
op = t.get_last_used_operation()
print(op.to_json(pretty=True))
Note: To ensure longitude, latitude order (x, y), add always_xy=True to force the longitude/latitude or easting/northing axis order.
Alternative: Use TransformerGroup class to get all available operations upfront, and then pick a transformation object that you want.
from pyproj.transformer import TransformerGroup
tg = TransformerGroup("EPSG:4258", "EPSG:32633")
print(tg.transformers[0].to_json()) # First transformer in the group
If you agree @snowman2, I suggest that this issue can be relabeled and closed.
Thanks @phaarnes 👍. I think this scenario would be a good one to document.