hermes - ✅(Solved) Fix [Bug]: example-dashboard plugin is discovered but has no built dist/, shows error banner on every install [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#28609Fetched 2026-05-20 04:03:12
View on GitHub
Comments
1
Participants
2
Timeline
5
Reactions
0
Author
Timeline (top)
labeled ×3commented ×1cross-referenced ×1

Error Message

But shipping a test-only fixture as a discoverable dashboard tab in the canonical install gives every user a broken tab + a confusing error banner out of the box. 4. Banner shows the error above; DevTools shows GET /dashboard-plugins/example/dist/index.js → 404.

  • Add a built dist/index.js (even a one-liner) so the tab renders without error, or

Fix Action

Workaround

Renaming plugins/example-dashboard/dashboard/manifest.jsonmanifest.json.disabled and restarting the dashboard hides the broken tab. But that change is destroyed on every hermes update.

PR fix notes

PR #28650: fix(dashboard): hide tab for plugins without a built entry (#28609)

Description (problem / solution / changelog)

Summary

Fixes #28609.

The bundled plugins/example-dashboard plugin ships a dashboard/manifest.json but no built dist/index.js. _discover_dashboard_plugins() registers it anyway, so every fresh hermes install shows a broken "Example" tab in the dashboard sidebar with the banner "无法加载此插件的脚本" and a 404 on GET /dashboard-plugins/example/dist/index.js.

We can't simply skip the plugin from discovery — tests/hermes_cli/test_web_server.py::TestPluginAPIAuth::test_plugin_route_allows_auth hits /api/plugins/example/hello, which depends on the example plugin's plugin_api.py being registered. So the fix targets only the UI surface.

Change

In _discover_dashboard_plugins() (hermes_cli/web_server.py), resolve the manifest's entry against the plugin's dashboard/ directory and check whether the file exists. When it doesn't:

  • force tab.hidden = True (in addition to honoring an explicit manifest hidden)
  • set the returned entry to None so the frontend treats it as "no script to fetch"
  • emit a _log.debug(...) so operators can grep for the cause

API routes and slot registration are untouched, so the example plugin's auth coverage test still passes.

Tests

  • Extended _write_plugin helper in tests/hermes_cli/test_web_server.py to also write a stub dist/index.js by default (opt-out via write_entry=False) so existing manifest-extension tests keep exercising the "entry present" path.
  • New test_missing_entry_hides_tab: manifest without an entry file → plugin still discovered, but tab.hidden is True and entry is None.
  • New test_present_entry_shows_tab: manifest with stubbed entry → tab.hidden falsy, entry == "dist/index.js".

pytest tests/hermes_cli/test_web_server.py — 147 passed locally.

Risk

  • Minimal surface change inside one function; no behavior change for plugins whose entry is built.
  • The hidden flag is a tab-level signal that the frontend already understands (tab.hidden is a documented manifest field), so no frontend change is required to drop the broken tab.
  • entry: null is a new value the frontend hasn't seen before; even without a frontend-side guard the broken behavior degrades to "no tab" rather than "tab + 404", which is strictly better than today.

Changed files

  • hermes_cli/web_server.py (modified, +10/-2)
  • tests/hermes_cli/test_web_server.py (modified, +36/-1)

Code Example

{
  "name": "example",
  "label": "Example",
  "description": "Example dashboard plugin — used by test suite for auth coverage",
  ...
  "entry": "dist/index.js"
}
RAW_BUFFERClick to expand / collapse

Bug

The bundled plugins/example-dashboard plugin is registered by the dashboard plugin discovery (/api/dashboard/plugins) but has no built dist/ directory, so the frontend immediately fails to load it with:

Example 无法加载此插件的脚本。请检查网络请求(dashboard-plugins/…)以及服务器上的插件路径。

(en: "Unable to load this plugin's script. Please check the network request (dashboard-plugins/…) and the plugin path on the server.")

The manifest itself is honest about its purpose:

{
  "name": "example",
  "label": "Example",
  "description": "Example dashboard plugin — used by test suite for auth coverage",
  ...
  "entry": "dist/index.js"
}

But shipping a test-only fixture as a discoverable dashboard tab in the canonical install gives every user a broken tab + a confusing error banner out of the box.

Reproduce

  1. Fresh hermes install / latest origin/main (verified on 1335ce996, Hermes Agent v0.14.0 (2026.5.16)).
  2. Open the dashboard.
  3. Click the Example tab in the sidebar.
  4. Banner shows the error above; DevTools shows GET /dashboard-plugins/example/dist/index.js → 404.

Expected

One of:

  • Don't ship the example plugin's manifest.json in the canonical install (move under a test fixtures path that discovery doesn't scan), or
  • Add a built dist/index.js (even a one-liner) so the tab renders without error, or
  • Have _discover_dashboard_plugins in hermes_cli/web_server.py skip manifests whose entry file doesn't exist on disk.

Workaround

Renaming plugins/example-dashboard/dashboard/manifest.jsonmanifest.json.disabled and restarting the dashboard hides the broken tab. But that change is destroyed on every hermes update.

Environment

  • Hermes Agent v0.14.0 (2026.5.16)
  • HEAD: 1335ce996 (latest origin/main: 1335ce996)
  • macOS, Python 3.11

Cross-ref

  • Related: #24116 (stale plugin cache) — different surface, same general area.
  • Related: #27631 (loader bypasses plugins.enabled config) — and once a config switch is honored, this plugin should default to disabled.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING