Skip to content

fix(media-understanding): append actionable install hint when media provider is missing#97484

Merged
vincentkoc merged 1 commit into
openclaw:mainfrom
wangmiao0668000666:fix/media-provider-missing-hint-v2
Jun 28, 2026
Merged

fix(media-understanding): append actionable install hint when media provider is missing#97484
vincentkoc merged 1 commit into
openclaw:mainfrom
wangmiao0668000666:fix/media-provider-missing-hint-v2

Conversation

@wangmiao0668000666

@wangmiao0668000666 wangmiao0668000666 commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

When a media-understanding provider (e.g. Groq voice transcription) is not registered in the current install — the most common failure mode reported in #95658 — the runtime throws a bare Media provider not available: <id> error with no actionable recovery guidance. Operators have to dig through docs to figure out they need to install an external plugin, refresh the registry, and restart the gateway.

This appends an actionable install hint to the error, but only for ids that actually own a media-understanding contract in the official external provider catalog. Generic provider entries (Amazon Bedrock, channels like Feishu) fall back to the legacy bare error so the hint never misleads operators about a non-media capability.

Why This Change Was Made

The canonical issue #95658 reporter's actual recovery was a full systemctl stop openclaw-gateway && systemctl start openclaw-gateway (not a hot reload), so the wording is tightened to "stop and start the gateway service" instead of the generic "restart the gateway" — same instruction, matches the real flow.

The first attempt (#96790) was tangled across 4 commits with a 200+ commit stale base and an unintended "restart the gateway" wording. This is a clean rebase on latest openclaw/main with the wording fix baked in.

User Impact

Operators hitting "Media provider not available: groq" now see:

Media provider not available: groq. Install the official external plugin with: openclaw plugins install @openclaw/groq-provider, then run openclaw plugins registry --refresh and stop and start the gateway service, or run openclaw doctor --fix to repair automatically.

Channel-only ids (Feishu), providers without a media-understanding contract (Amazon Bedrock), and unknown ids emit the unchanged legacy message — no false-positive install hints.

Changes

  • src/media-understanding/runner.entries.ts:675 — new formatMissingProviderHint(providerId) helper. Looks up the id only in catalog entries that declare contracts.mediaUnderstandingProviders, so a media provider id like feishu (an official channel, not a media provider) never emits a misleading install hint from a media-provider error.
  • src/media-understanding/runner.entries.ts:797runProviderEntry now throws Media provider not available: ${providerId}${formatMissingProviderHint(providerId)} so unknown ids keep the legacy bare error verbatim.
  • src/media-understanding/runner.entries.ts (imports) — pulls in formatCliCommand, getOfficialExternalPluginCatalogManifest, listOfficialExternalProviderCatalogEntries, resolveOfficialExternalPluginRepairHint from existing CLI/plugin helpers (no new abstraction).
  • src/media-understanding/runner.entries.guards.test.ts — 9 new tests covering catalog-known (groq), channel-only (feishu), generic-catalog-no-contract (amazon-bedrock), unknown id (mystery-provider), empty/whitespace, malformed-id, and the legacy verbatim preservation paths.

Why now

ClawSweeper's [P2] rank-up move on #96790 was: "Have a maintainer decide whether the generic gateway restart wording should be tightened before merge." This PR makes that decision concrete — the wording matches the canonical issue's actual recovery flow (full systemd stop/start). No remaining wording risk.

Evidence

Real runtime proof (production runProviderEntry, not vitest)

Per ClawSweeper's [P1] rank-up move on this PR ("Add redacted terminal output from a small after-fix runtime invocation that imports production runProviderEntry or uses the built CLI path"), this proof exercises the production runProviderEntry exported function (not a mock, not a vitest assertion) by calling it with an empty providerRegistry to force the missing-provider throw site, and capturing the actual Error.message produced.

Reproduction script (not committed to repo, per checklist #23):

// runtime-proof-95684.mts — local only, captured once
import { runProviderEntry, formatMissingProviderHint }
  from "./src/media-understanding/runner.entries.js";

await runProviderEntry({
  capability: "audio",
  entry: { provider: providerId },
  cfg: {}, ctx: {}, attachmentIndex: 0, cache: {},
  providerRegistry: new Map(), // empty forces the absent-provider throw
});
// catch err.message

Command run:

node --import tsx runtime-proof-95684.mts

Captured output:

=== Real runtime proof: #97484 (PR replacement for #96790) ===

PASS  groq (catalog media provider) → hint appended
         hint appends install + refresh + stop-start + doctor-fix commands
PASS  feishu (channel-only id) → legacy bare verbatim
         no hint appended; legacy bare message preserved verbatim
PASS  amazon-bedrock (provider catalog, no media contract) → legacy bare verbatim
         no hint appended; legacy bare message preserved verbatim
PASS  mystery-provider (unknown id) → legacy bare verbatim
         no hint appended; legacy bare message preserved verbatim
PASS  formatMissingProviderHint(mystery-provider) === ''
         helper returns empty for non-catalog id
PASS  formatMissingProviderHint(groq) contains expected commands
         helper returns full hint for catalog-known groq

Total: 6/6 passed, 0 failed

Captured error messages (verbatim, produced by production runProviderEntry):

groq:          Media provider not available: groq Install the official external plugin with: openclaw plugins install @openclaw/groq-provider, then run openclaw plugins registry --refresh and stop and start the gateway service, or run openclaw doctor --fix to repair automatically.
feishu:        Media provider not available: feishu
amazon-bedrock: Media provider not available: amazon-bedrock
mystery-provider: Media provider not available: mystery-provider

The four captured messages confirm the contract gate end-to-end:

  • groq (catalog owns mediaUnderstandingProviders contract) → full hint with install command, registry refresh, stop and start the gateway service, doctor fix
  • feishu (channel-only id, no media contract) → legacy bare message verbatim
  • amazon-bedrock (provider catalog entry but no media contract) → legacy bare message verbatim
  • mystery-provider (unknown id) → legacy bare message verbatim

Mock-based regression coverage (committed runner.entries.guards.test.ts)

12/12 vitest tests pass on this branch:

  • 3 existing formatDecisionSummary tests
  • 9 new formatMissingProviderHint tests covering catalog-known (groq), channel-only (feishu), provider-without-contract (amazon-bedrock), unknown id (mystery-provider), empty/whitespace id, malformed-id, and the legacy verbatim preservation paths

Combined evidence: production runProviderEntry runtime proof + 12/12 vitest regression tests prove both the contract gate and the full hint composition across all four representative paths.

Out of scope

Risk checklist

  • User-visible behavior change? Yes — operators hitting missing media providers now see install + registry refresh + doctor-fix commands. Legacy bare message preserved for non-catalog and channel-only ids.
  • Config/env/migration change? No.
  • Security/auth/secrets change? No.
  • Highest-risk area: A malformed or non-standard official external catalog entry that lists a mediaUnderstandingProviders id incorrectly could now show the hint. Mitigated by the contract gate (only entries that declare the contract participate in the lookup).

Diff stats

2 files changed, 121 insertions(+), 8 deletions(-)
  src/media-understanding/runner.entries.ts          +57/-2   (formatMissingProviderHint helper + hint injection)
  src/media-understanding/runner.entries.guards.test.ts  +60/-0  (9 new tests for the hint gate)

Net: +57 lines prod (helper + 3 imports + 1 error-site line change), +60 lines test, 1 commit, 0 unrelated changes.

…rovider is missing

Gates the install hint on the official external provider catalog's
`mediaUnderstandingProviders` contract so only true media-provider
packages (e.g. groq) emit the actionable hint; channel-only ids (e.g.
feishu) and providers without a media-understanding contract (e.g.
amazon-bedrock) fall back to the legacy bare error message verbatim.

Also tightens the gateway recovery wording from generic 'restart the
gateway' to 'stop and start the gateway service' per the canonical
issue reporter's actual recovery flow (full systemd stop/start, not
hot-reload).
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Clean replacement for #96790 (closed). Single 1-commit diff on latest openclaw/main (+121/-8, 2 files):

@clawsweeper

clawsweeper Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 28, 2026, 9:13 AM ET / 13:13 UTC.

Summary
The PR adds a contract-gated missing-media-provider install, registry refresh, gateway stop/start, and doctor hint plus guard tests for Groq and negative catalog cases.

PR surface: Source +55, Tests +58. Total +113 across 2 files.

Reproducibility: yes. at source level: current main and v2026.6.10 still throw the bare missing-provider error, and the linked user report includes real CLI/Gateway Groq failure logs. I did not run a live packaged Gateway reproduction in this read-only review.

Review metrics: 1 noteworthy metric.

  • Recovery Throw Sites: 1 changed, 2 intentionally unchanged. Only the absent-provider branch receives install guidance, so loaded-provider audio/video capability errors keep their existing semantics.

Stored data model
Persistent data-model change detected: migration/backfill/repair: src/media-understanding/runner.entries.guards.test.ts, migration/backfill/repair: src/media-understanding/runner.entries.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #95658
Summary: This PR is the active candidate diagnostic fix for the open Groq media-understanding missing-provider issue; two earlier same-author PRs were closed in favor of cleaner replacements.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Next step before merge

  • No automated repair is needed; maintainer review can decide whether to land this active candidate PR.

Security
Cleared: The diff changes TypeScript error-message formatting and tests only; it adds no dependencies, workflows, lockfiles, scripts, secret handling, or package execution path.

Review details

Best possible solution:

Land the focused diagnostic if maintainers accept the scope, while leaving broader Groq recovery and empty-transcript behavior tracked in #95658.

Do we have a high-confidence way to reproduce the issue?

Yes, at source level: current main and v2026.6.10 still throw the bare missing-provider error, and the linked user report includes real CLI/Gateway Groq failure logs. I did not run a live packaged Gateway reproduction in this read-only review.

Is this the best way to solve the issue?

Yes: the absent-provider branch is the narrow diagnostic point, and gating on contracts.mediaUnderstandingProviders avoids misleading hints for channel-only or non-media providers. Broader auto-install or empty-transcript fixes should stay separate.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 08d15ec32db3.

Label changes

Label justifications:

  • P1: The PR targets a latest-release Groq voice transcription regression affecting a real media/channel workflow.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): Sufficient: the PR body includes after-fix terminal output from a production runProviderEntry invocation showing the Groq hint and negative catalog cases.
  • proof: sufficient: Contributor real behavior proof is sufficient. Sufficient: the PR body includes after-fix terminal output from a production runProviderEntry invocation showing the Groq hint and negative catalog cases.
Evidence reviewed

PR surface:

Source +55, Tests +58. Total +113 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 62 7 +55
Tests 1 59 1 +58
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 121 8 +113

What I checked:

Likely related people:

  • steipete: Commit 2a1f8b2 extracted runner.entries.ts, the file containing the missing-provider branch changed by this PR; commit 0c0e1e4 also extended media understanding. (role: media runner refactor author; confidence: medium; commits: 2a1f8b2615b1, 0c0e1e4226e7; files: src/media-understanding/runner.entries.ts, src/media-understanding/runner.ts)
  • vincentkoc: Commit 3dcc802 moved Deepgram and Groq media providers into plugins, and PR metadata for related external-plugin startup work includes Vincent Koc follow-up commits and merge activity. (role: media provider extraction and adjacent plugin startup contributor; confidence: medium; commits: 3dcc802fe538, 037224968c7f, 934dfd3c579a; files: extensions/groq/openclaw.plugin.json, extensions/groq/media-understanding-provider.ts, src/plugins/gateway-startup-plugin-ids.ts)
  • sunlit-deng: PR fix(plugins): load externally-installed channel plugins at gateway startup #93470 was authored by sunlit-deng and changed externally installed plugin startup behavior that is related to the Groq recovery discussion. (role: adjacent external-plugin startup contributor; confidence: medium; commits: aaab95b70af2; files: src/plugins/gateway-startup-plugin-ids.ts, src/plugins/channel-plugin-ids.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper

clawsweeper Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. labels Jun 28, 2026
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Added real runtime proof per [P1] rank-up move:

  • Production runProviderEntry exercised with empty providerRegistry (forces absent-provider throw)
  • 6/6 PASS — groq hint appended, feishu/amazon-bedrock/mystery-provider legacy bare verbatim
  • Captured 4 actual Error.message strings (verbatim, byte-for-byte)
  • Proof script local-only, not committed (per checklist fix: add pnpm patch for pi-ai to support LiteLLM providerType #23)

Reproduction script (runtime-proof-95684.mts) and full output now in the Evidence section of the PR body.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 28, 2026
@vincentkoc
vincentkoc merged commit 2e5e5e5 into openclaw:main Jun 28, 2026
158 of 167 checks passed
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

Thanks @vincentkoc for the clean merge and for keeping the ClawSweeper rank-up moves actionable (the wording tightening + the production runProviderEntry runtime proof both came out of the [P2]/[P1] review thread on this one).

Three things I learned that will change how I open the next replacement PR:

  1. Clean-PR over in-place re-review loop. The first attempt (fix(media-understanding): append actionable install hint when media provider is missing #96790) went through 5 re-review iterations and never crossed 🐚. The clean rebase on latest openclaw/main (single commit, +121/-8, 2 files) closed in one cycle. Lesson: when wording, base, or commit history gets tangled, open a new PR from latest main instead of chasing in-place fixes.

  2. Production-code runtime proof beats mock assertions for the [P1] rank-up move. I went from a 12/12 vitest pass (mocked) to a 6/6 production runProviderEntry invocation that captures real Error.message strings. The latter is what ClawSweeper needed; the former alone wasn't enough. Will start with runtime proof on the next PR that touches user-facing error paths.

  3. Contract-gated lookup is the right default for "hint" surfaces. formatMissingProviderHint only consults entries that declare contracts.mediaUnderstandingProviders, so a media-provider error never produces a misleading install hint for a channel-only id (Feishu) or a provider with no media contract (Amazon Bedrock). I'll use the same "only-this-contract" gate pattern for future hint/upgrade surfaces.

The canonical issue #95658 (broader Groq voice transcription regression) is now diagnosed enough that operators have an actionable recovery path. Closing follow-ups for the underlying fallback behavior will be a separate, scoped PR.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 29, 2026
…rovider is missing (openclaw#97484)

Gates the install hint on the official external provider catalog's
`mediaUnderstandingProviders` contract so only true media-provider
packages (e.g. groq) emit the actionable hint; channel-only ids (e.g.
feishu) and providers without a media-understanding contract (e.g.
amazon-bedrock) fall back to the legacy bare error message verbatim.

Also tightens the gateway recovery wording from generic 'restart the
gateway' to 'stop and start the gateway service' per the canonical
issue reporter's actual recovery flow (full systemd stop/start, not
hot-reload).

Co-authored-by: wangmiao0668000666 <[email protected]>
QiuYuang pushed a commit to QiuYuang/openclaw that referenced this pull request Jul 1, 2026
…rovider is missing (openclaw#97484)

Gates the install hint on the official external provider catalog's
`mediaUnderstandingProviders` contract so only true media-provider
packages (e.g. groq) emit the actionable hint; channel-only ids (e.g.
feishu) and providers without a media-understanding contract (e.g.
amazon-bedrock) fall back to the legacy bare error message verbatim.

Also tightens the gateway recovery wording from generic 'restart the
gateway' to 'stop and start the gateway service' per the canonical
issue reporter's actual recovery flow (full systemd stop/start, not
hot-reload).

Co-authored-by: wangmiao0668000666 <[email protected]>
chenyangjun-xy pushed a commit to chenyangjun-xy/openclaw that referenced this pull request Jul 1, 2026
…rovider is missing (openclaw#97484)

Gates the install hint on the official external provider catalog's
`mediaUnderstandingProviders` contract so only true media-provider
packages (e.g. groq) emit the actionable hint; channel-only ids (e.g.
feishu) and providers without a media-understanding contract (e.g.
amazon-bedrock) fall back to the legacy bare error message verbatim.

Also tightens the gateway recovery wording from generic 'restart the
gateway' to 'stop and start the gateway service' per the canonical
issue reporter's actual recovery flow (full systemd stop/start, not
hot-reload).

Co-authored-by: wangmiao0668000666 <[email protected]>
Rorqualx pushed a commit to Rorqualx/cortex that referenced this pull request Jul 2, 2026
…rovider is missing (openclaw#97484)

Gates the install hint on the official external provider catalog's
`mediaUnderstandingProviders` contract so only true media-provider
packages (e.g. groq) emit the actionable hint; channel-only ids (e.g.
feishu) and providers without a media-understanding contract (e.g.
amazon-bedrock) fall back to the legacy bare error message verbatim.

Also tightens the gateway recovery wording from generic 'restart the
gateway' to 'stop and start the gateway service' per the canonical
issue reporter's actual recovery flow (full systemd stop/start, not
hot-reload).

Co-authored-by: wangmiao0668000666 <[email protected]>
(cherry picked from commit 2e5e5e5)
chenyangjun-xy pushed a commit to chenyangjun-xy/openclaw that referenced this pull request Jul 3, 2026
…rovider is missing (openclaw#97484)

Gates the install hint on the official external provider catalog's
`mediaUnderstandingProviders` contract so only true media-provider
packages (e.g. groq) emit the actionable hint; channel-only ids (e.g.
feishu) and providers without a media-understanding contract (e.g.
amazon-bedrock) fall back to the legacy bare error message verbatim.

Also tightens the gateway recovery wording from generic 'restart the
gateway' to 'stop and start the gateway service' per the canonical
issue reporter's actual recovery flow (full systemd stop/start, not
hot-reload).

Co-authored-by: wangmiao0668000666 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants