DEV Community

Rehan Sanjay Venkatesan
Rehan Sanjay Venkatesan

Posted on

I installed all 67 Pipecat community plugins. 19 of them don't work.

Pipecat's docs list every community-maintained plugin on one page: speech-to-text, text-to-speech, serializers, VAD, analytics, transports. Pick a vendor, pip install, follow the snippet.

For 19 of the 67 listed this morning, that doesn't work. The install fails, or the import raises, or the package pins a version of Pipecat from a year ago and quietly drags your whole environment backwards.

Nobody is hiding this. It's just that nothing was checking.

What the checker does

Every night, for each plugin on the supported-services page:

  1. Create a fresh environment.
  2. Install the plugin together with the latest pipecat-ai release on PyPI — what a new user gets today.
  3. Do it again against pipecat-ai main — what users get in the next release.
  4. Import the plugin and construct every Pipecat service class it defines.

No API keys are used anywhere, so this doesn't test whether a provider's servers answer. It tests the part that breaks far more often: install, import, and API shape — renamed or removed Pipecat symbols, new abstract methods, version pins.

The plugin list is re-read from the docs on every run, so new plugins are picked up automatically. That matters: the page had 56 entries three weeks ago and has 67 today.

Results from this morning's run, against pipecat-ai 1.12.0:

Status Count
Works 48
Partial 1
Broken on import 10
Pinned to an older Pipecat 5
Can't be installed at all 3

The failures cluster, and that's the interesting part

Six plugins die on the same line. In Pipecat 1.8 the settings sentinel _NotGiven was removed from pipecat.services.settings — it's NotGiven in pipecat.utils.types now. Six plugins still import the old name, so they raise before doing anything else:

ImportError: cannot import name '_NotGiven' from 'pipecat.services.settings'
Enter fullscreen mode Exit fullscreen mode

Six different companies, six separate repositories, one upstream rename. Each fix is a single import line.

Three more broke on renamed frames. One imports StartInterruptionFrame, another LLMMessagesFrame, another assert_given — none of which exist under those names any more.

Two are missing their own dependency. The plugin expects a vendor SDK that isn't installable from where it looks for it.

Five pin Pipecat backwards. One requires pipecat-ai>=0.0.97,<0.1.0. Another wants ==0.0.105. A third pins ==1.8.1 exactly. These don't error — which is worse. Your resolver silently downgrades Pipecat, or refuses to solve, and the reason isn't obvious from the traceback you eventually get.

Three can't be installed at all. Two checkouts have neither a pyproject.toml nor a setup.py, so there's nothing to install. One isn't on PyPI under the name the docs use.

This is not upstream's fault

It would be easy to read the _NotGiven cluster as Pipecat breaking its ecosystem. It isn't.

The 1.8.0 changelog flagged the change with a ⚠️ and spelled out the migration:

NOT_GIVEN, NotGiven, is_given() and assert_given() now come from pipecat.utils.types and are no longer importable from pipecat.services.settings. The private pipecat.services.settings._NotGiven is now the public pipecat.utils.types.NotGiven.

They announced it, named the destination, and were right that the old name was private — plugin authors were importing an underscore-prefixed symbol out of someone else's module, which was always going to be fragile.

The supported-services page is equally clear about ownership: community plugins are distributed separately and issues go to their own repositories.

So upstream did the things you'd ask for. The breakage happened anyway.

Why it keeps happening

Community plugins live in their own repositories, usually maintained by one engineer at the vendor. Pipecat ships often and moves fast, which is a virtue. But a plugin repo has no CI that installs against Pipecat main, so an upstream rename doesn't produce a red build anywhere — it produces a broken install six weeks later, for a user who has no relationship with either party and will simply choose a different vendor.

That's the gap: the breakage is public, deterministic and cheap to detect, and there was no place where anyone looked at all of them at once.

It measures recovery too

Between two runs in September, one plugin loosened its pin and moved from "needs older Pipecat" to "works". That's the part I didn't expect to enjoy: the table isn't a wall of shame, it's a live picture. Anything on it can move, and most of these are one line away from moving.

Running against main as well as the current release is deliberate, and it's the part I'd most like vendors to use. A plugin that breaks against main today has until the next Pipecat release to fix it, rather than finding out from an issue after the fact.

If you're choosing a plugin

  • Check the pin before you check the features. Four of the five pinned plugins will silently downgrade Pipecat in your environment rather than fail, and you'll debug it as something else entirely.
  • An import test is a five-second question. python -c "import pipecat_<name>" in a fresh environment tells you more than a README.
  • Check when the repo last moved. All ten broken plugins have been broken since late August. That's visible from the outside before you commit.

I've been sending the fixes

Rather than just publishing a list, I opened PRs for the ones I could fix from outside — eleven of them across eleven repositories.

What happened next is its own post, and it isn't the happy ending: three weeks on, none of them have merged. I'll write that one up separately, because the result surprised me more than the original findings did.

The repo, with the full table and the nightly results:
https://github.com/Rehansanjay/pipecat-plugin-health

If your plugin is on the broken list and you'd rather have a PR than a bug report, say so and I'll send one.

Top comments (1)

Collapse
 
arhancanli profile image
Arhan Canli •

The table adds up (48 + 1 + 10 + 5 + 3 = 67), and so does the headline: 19 is the 10 import failures, the 5 pins, the 3 uninstallable ones and the 1 partial. Worth knowing when quoting it, because the pinned five are the only group where nothing has been shown to be broken. A plugin pinned to ==1.8.1 fails to resolve, but it may run fine on 1.12.

That is checkable with the machinery you already have: install the five with --no-deps next to the current pipecat-ai, then run the same import and construct step. Any that pass are "pin too tight" (a one-line fix for the maintainer). Any that fail are real API breaks hiding behind the pin. Those are two different messages to send a vendor, and the single "pinned to an older Pipecat" row merges them.

One more thing for the table: record the pipecat-ai version next to each run. "Works against 1.12.0" is a dated claim, and with a nightly run the recovery you mention (a plugin loosening its pin) is only readable if the version is in the row.

Where do the three uninstallable ones sit in the count, as failures or as a separate class from the 16 that were actually tried?