System designTroubleshooting

ROS launch package not found: install the wrapper in your container

A package not found error at ros2 launch means the wrapper is missing from the running environment. Install it in the same image, source the overlay, verify.

LumaSpec Vision8 min read Share on LinkedIn

On this page 7 sections
  1. 01What the error text is telling you
  2. 02The three causes, most likely first
  3. 03Install the wrapper in the container, step by step
  4. 04Worked example: built in one container, launched from another
  5. 05Make the install survive the next restart
  6. 06After the launch works
  7. 07Questions

ros2 launch stops within a second or two with "Caught exception when trying to load file of format [py]: package '...' not found". The launch file is usually fine. The message means the launch process searched the ROS 2 environment of the shell it runs in, found no package registered under that name, and gave up before starting a single node. Camera wrappers hit this constantly, because the wrapper was built in one container and launched from another, or built yesterday and launched from a fresh shell today. One command separates those cases. Here is the test, the fix for each cause, and the image changes that keep the wrapper installed across container restarts.

What the error text is telling you

Two messages arrive on one line. The outer one, "Caught exception in launch", is the generic complaint of a Python launch file that raised while loading. The inner one is the diagnosis. The loader found your file, began executing it, and the first package lookup — a get_package_share_directory call, or the package name you passed to ros2 launch — failed because nothing of that name is registered in this environment. Read it as: the launch file exists, the package it names does not, here.

Compare the neighboring error, "launch file '...' not found". There the package resolved but the file is missing from its launch directory, which needs a filename or path fix. When the message says package, work the environment tests below before touching the file.

The same install-then-prove discipline applies to camera packages that never registered cleanly: ROS camera package unavailable: fix the install, prove the stream covers that case.

The three causes, most likely first

Run this one test in the exact shell you launch from:

ros2 pkg list | grep <package_name>

<package_name> is the string from the error, typed exactly. One line of output means the package is registered and your problem is a name mismatch; zero lines means one of the causes below. The name here is an illustrative stand-in for your own.

Cause 1: the overlay was never sourced in this shell. You built the wrapper, maybe yesterday or in another terminal, and the current shell only knows the underlay. Check echo $AMENT_PREFIX_PATH: a healthy setup lists the distribution prefix first, then your workspace install directory. If the workspace entry is missing, source it and run the grep again.

Cause 2: the wrapper was never installed in this image. The common container case. The launch file was copied in, but the package it references was built in a different container, possibly one that no longer exists. Anything installed after the image was built lives in that container's writable layer, and a new docker run from the base image starts without it. ls ~/ros2_ws/install prints nothing when the build never happened here.

Cause 3: the build failed for this package, so it never registered. The colcon summary counts finished and failed packages; if yours is absent from the finished count, the log under log/ names the missing dependency or the compile error. Third-party wrappers fail on dependencies often — the same diagnosis applies to a CAN driver package build that fails in ROS 2, where the failure surfaces in the build log, not at launch.

The failure is not container-specific either. A SLAM launch file that names a missing node is diagnosed the same way: ask what the running environment can load before editing the file.

Test observation What it proves First fix
ros2 pkg list prints nothing at all No setup file is sourced, not even the underlay source /opt/ros/<distro>/setup.bash
The full list works, grep returns zero lines Your package is absent from this environment Source the overlay, or install the package
Grep returns one line, launch still fails Name mismatch against the declared package name Compare the <name> tag in package.xml character by character

Install the wrapper in the container, step by step

Work in the container you will launch from, not a throwaway:

  1. Open a shell in it: docker exec -it <container> bash. Every later test and the launch happen in this shell.
  2. Source the underlay: source /opt/ros/<distro>/setup.bash, with your ROS 2 distribution in place of <distro>.
  3. Put the wrapper source into a workspace: clone the wrapper repository under ~/ros2_ws/src.
  4. Install its declared dependencies: cd ~/ros2_ws && rosdep install --from-paths src --ignore-src -r -y.
  5. Build just that package: colcon build --packages-select <wrapper_package>. A single wrapper builds in well under a minute on a typical machine; if it runs many minutes, rosdep is pulling large dependencies.
  6. Source the overlay: source install/setup.bash from the workspace root.
  7. Prove registration: ros2 pkg list | grep <wrapper_package> must print exactly one line.
  8. Launch: ros2 launch <wrapper_package> <camera>.launch.py. When the next failure is a missing topic rather than a missing package, ROS 2 camera topic missing: find the name the node really publishes is the follow-up.

Worked example: built in one container, launched from another

The case: a stereo camera wrapper was built inside a vendor GPU image days ago, in a container that has since been removed. Today you start a fresh container from the same base image, copy the launch file in, and run it. Inputs: the error line the launch printed; the two diagnostic commands, ros2 pkg list and echo $AMENT_PREFIX_PATH; and the package name stereo_camera_wrapper, an illustrative stand-in for the name in your own error.

The rule: a launch process resolves package names against the prefixes listed in AMENT_PREFIX_PATH, and every sourced setup file adds exactly one prefix to that list.

$ ros2 launch stereo_camera_wrapper stereo.launch.py
[ERROR] [launch]: Caught exception in launch (see debug for traceback): Caught exception when trying to load file of format [py]: package 'stereo_camera_wrapper' not found
$ echo $AMENT_PREFIX_PATH
/opt/ros/humble
$ ros2 pkg list | grep stereo_camera_wrapper
(no output — 0 lines)
$ source ~/ros2_ws/install/setup.bash
$ echo $AMENT_PREFIX_PATH
/opt/ros/humble:/home/user/ros2_ws/install
$ ros2 pkg list | grep stereo_camera_wrapper
stereo_camera_wrapper

Read the counts. Before sourcing, the path holds 1 entry and grep returns 0 lines. After sourcing, 1 + 1 = 2 entries — underlay plus overlay — and grep returns exactly 1 line. The decision rule: 1 line means launch will resolve the package, so run it. 0 lines means the environment is the fault; do not edit the launch file, because it is not the failing part. If you know you built in that image and the workspace path still never appears, the workspace never made it into this container — cause 2, build here or rebuild the image.

Make the install survive the next restart

Fixing a running container works exactly once. A docker commit of it captures the workspace, along with everything else you touched, and nothing records how the image was made. As a sizing anchor, a wrapper plus its dependencies typically adds on the order of 200-500 MB to an image — illustrative, measured once with docker images before and after — so track it in the Dockerfile, not in a writable layer. Put the install in the Dockerfile instead:

RUN git clone <wrapper_repository> /ros2_ws/src/<wrapper_package>
RUN cd /ros2_ws && rosdep install --from-paths src --ignore-src -r -y
RUN cd /ros2_ws && colcon build

Then make every shell source the overlay by itself — add the source line to the image entrypoint or the shell profile, so a new terminal never starts without the overlay. A pattern worth copying from production ROS images: keep a development image with the build toolchain and a deployment image that only receives the finished install/ directory. When a development image grows without anyone noticing, this unexpected package-size fix for a ROS development container walks the cleanup from build to deploy image.

After the launch works

Once the wrapper runs, the failures that follow are configuration and scaling ones, not install ones. A launch file can override settings you configured elsewhere — ROS launch overrides your camera config: the schema mask wins explains which value wins. Adding a second device is easier with a plan: multiple cameras ROS launch: plan acquisition and synchronization. And when the wrapper exists only to pull one stream, the SDK route is often shorter — reading IMU data from a 3D camera through its SDK, not ROS skips the wrapper for that stream entirely.

If you are choosing the camera this wrapper will drive, browse the 3D camera category or the camera finder; more integration notes sit on the systems topic page.

Cameras3D sensors

Laser profilers and stereo 3D cameras

170 models · from $699.00

For a specific integration question, the contact page reaches the applications team.

Questions

Why does ros2 pkg list print nothing at all?

An empty list means the shell has no ROS 2 environment at all: AMENT_PREFIX_PATH is unset and not even the underlay under /opt/ros is registered. Source the distribution's setup file, for example /opt/ros/humble/setup.bash, then run the list again. After that, an empty grep for your own package points to the overlay instead.

Can the wrapper stay on the host while ROS runs in the container?

The launch process resolves packages from its own environment, so a host install is invisible to it unless you mount the workspace into the container and source it there. The cleaner split is to run the driver where its SDK lives and pass topics over the network; both sides then need compatible ROS 2 versions and matching middleware settings for discovery.

Why is the wrapper gone after I recreate the container?

Everything you installed after the image was built lives in that container's writable layer, and docker run from the base image starts without it. Commit the working container to a new image tag, or better, add the clone, rosdep and colcon build steps to the Dockerfile so every new container gets the wrapper at build time.

Where does ros2 launch look for launch files?

It resolves the package first, then reads the file from that package's share directory, share/<package_name>/launch. Both steps need the package prefix registered in the environment, which is why a missing source step produces the same package-not-found error for a file that exists on disk.

Does the package name in the launch file have to match exactly?

Yes, character for character and case-sensitive: the string you pass to ros2 launch is matched against the name tag in the package's package.xml, not the folder name under src/. A capital letter or a missing underscore fails the same lookup and prints the same error, so compare the two strings before rebuilding anything.