# tf2.BufferCore::lookupTransform: Can't find transform from 'base_link' to 'map', error: 'map' passed to lookupTransform argument target_frame does not exist

- **ID:** `ros2/tf2-buffer-core-transform-timeout`
- **Domain:** ros2
- **Category:** runtime_error
- **Error Code:** `TF2_LOOKUP_001`
- **Verification:** ai_generated
- **Fix Rate:** 90%

## Root Cause

The tf2 buffer does not have the requested transform due to a missing broadcaster, wrong frame name, or the transform not being published yet (e.g., robot_state_publisher not running or static_transform_publisher misconfigured).

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| Humble | active | — | — |
| Iron | active | — | — |
| Jazzy | active | — | — |
| Rolling | active | — | — |

## Workarounds

1. **Ensure the static_transform_publisher for the 'map' to 'odom' frame is running in the launch file: <node pkg="tf2_ros" exec="static_transform_publisher" args="0 0 0 0 0 0 map odom"/>** (90% success)
   ```
   Ensure the static_transform_publisher for the 'map' to 'odom' frame is running in the launch file: <node pkg="tf2_ros" exec="static_transform_publisher" args="0 0 0 0 0 0 map odom"/>
   ```
2. **Check the frame names in the URDF and ensure robot_state_publisher publishes the correct transforms: ros2 run robot_state_publisher robot_state_publisher --ros-args -p robot_description:="$(xacro my_robot.urdf.xacro)"** (85% success)
   ```
   Check the frame names in the URDF and ensure robot_state_publisher publishes the correct transforms: ros2 run robot_state_publisher robot_state_publisher --ros-args -p robot_description:="$(xacro my_robot.urdf.xacro)"
   ```
3. **Add a transform listener with a retry loop and a timeout of 2 seconds, logging the available frames for debugging: try: transform = tf_buffer.lookup_transform('map', 'base_link', rclpy.time.Time(), timeout=rclpy.duration.Duration(seconds=2.0)); except tf2.LookupException: self.get_logger().info('Available frames: ' + str(tf_buffer.all_frames_as_string()))** (80% success)
   ```
   Add a transform listener with a retry loop and a timeout of 2 seconds, logging the available frames for debugging: try: transform = tf_buffer.lookup_transform('map', 'base_link', rclpy.time.Time(), timeout=rclpy.duration.Duration(seconds=2.0)); except tf2.LookupException: self.get_logger().info('Available frames: ' + str(tf_buffer.all_frames_as_string()))
   ```

## Dead Ends

- **Set the lookup timeout to a very high value (e.g., 10 seconds)** — Timeout doesn't create the missing transform; it only delays the error. (95% fail)
- **Change the target_frame to 'odom' in all lookup calls** — This may work temporarily but breaks applications that need the 'map' frame for global planning. (80% fail)
- **Hardcode the transform as a static transform in the code** — Static transforms don't update with robot movement; the robot will get stuck or collide. (90% fail)
