Skip to content

Dashboard buildDashboard() throws insertBefore NotFoundError — plugin init aborts, Ctrl+K and browser chat blocked #166

Description

@Dhivya-Bharathy

Dashboard buildDashboard() throws insertBefore NotFoundError — plugin init aborts, Ctrl+K and browser chat blocked


Summary

Problem statement

On fresh clone @ 0b62e7d, loading any dashboard-style PraisonAIUI app in Chromium or Edge throws a console error during buildDashboard():

NotFoundError: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.

The dashboard plugin fails to initialize. Downstream initializers — including initCommandPalette() (Ctrl+K) and view modules that depend on a fully built shell — never run. Browser chat UI (#chat-input) does not mount even though REST chat APIs work.

Business impact

Technical impact

  • plugin-loader.js reports [AIUI] Failed to load plugin "dashboard".
  • Partial DOM shell may render; chat compose, command palette overlay, and dependent plugin hooks are absent.
  • Playwright E2E: ctrl_k_palette fails; browser:chat_input fails on LLM pass.

User impact

  • Ctrl+K does nothing (no .db-cmdk-overlay).
  • Chat page navigates but no message textarea appears.
  • Console shows repeated warnings on every reload and multi-tab open.

Regression impact

  • Command palette code exists in dashboard.js (initCommandPalette) but never executes when shell:header slot has content.
  • Likely introduced when shell header slot support was added without reordering DOM append sequence.

Repository Information

Field Value
Repository MervinPraison/PraisonAIUI
Commit SHA 0b62e7dcec89767a49a5495ae6522b302c0fd232
Branch main (latest at validation time)
Version 0.3.124
Environment Fresh shallow clone, editable install
OS Windows 10.0.19045
Python 3.13.2
Node v22.22.0
Browser Chromium (Playwright headless), Microsoft Edge
LLM Provider OpenAI (API validated separately; UI blocked)
Configuration Default dashboard examples
Database JSONFileDataStore (default)
Server mode Standalone :8082 (15-dashboard-test) and Gateway :8083 (18-full-chat)
Validation date 2026-06-26

Preconditions

  1. Fresh clone and editable install:
    git clone --depth 1 https://github.com/MervinPraison/PraisonAIUI.git
    cd PraisonAIUI
    pip install -e ".[dev]"
    aiui build
  2. Start dashboard example:
    cd examples/python/15-dashboard-test
    python app.py
    Server listens on http://127.0.0.1:8082.
  3. Optional gateway mode (same bug):
    cd examples/python/18-full-chat
    set PORT=8083
    python app.py
  4. Browser with DevTools console open.
  5. Trigger condition: shell:header slot renders at least one child (default template populates header content in built dashboard).

Reproduction Steps

  1. Complete preconditions above.
  2. Open http://127.0.0.1:8082/ in Chrome or Edge.
  3. Open DevTools → Console tab.
  4. Wait for networkidle (~2–5 s).
  5. Observe console within 1 s of load:
    • Expected error referencing dashboard.js:1308.
  6. Press Ctrl+K — wait 2 s.
    • No command palette overlay appears.
  7. Click Chat in sidebar — wait 2 s.
    • No #chat-input textarea in DOM (document.querySelector('#chat-input')null).
  8. Optional Playwright:
    cd competitive-analysis/full-validation-fresh-20260612/browser-e2e
    python run_browser_e2e.py
    python run_llm_browser_e2e.py

Actual Result

Console output (captured 2026-06-26, Chromium @ :8082)

[AIUI] Failed to load plugin "dashboard": NotFoundError: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
    at buildDashboard (http://127.0.0.1:8082/plugins/dashboard.js?v=1782452566208:1308:41)
    at async Object.init (http://127.0.0.1:8082/plugins/dashboard.js?v=1782452566208:1233:3)
    at async loadPlugin (http://127.0.0.1:8082/plugins/plugin-loader.js?v=1782451154:39:9)
    at async Promise.allSettled (index 1)
    at async HTMLDocument.main (http://127.0.0.1:8082/plugins/plugin-loader.js?v=1782451154:116:7)

Same error on :8083 (LLM browser pass, console capture from Playwright).

Source code at failure point

  const shellHeader = document.createElement('div');
  shellHeader.id = 'db-shell-header-slot';
  renderSlot('shell:header', shellHeader);
  if (shellHeader.children.length) root.insertBefore(shellHeader, main);
  root.appendChild(main);

main is not yet a child of root when insertBefore(shellHeader, main) executes — invalid per DOM spec.

Playwright / browser E2E

Test Result
ctrl_k_palette ❌ FAIL — .db-cmdk-overlay not visible
browser:chat_input ❌ FAIL — no textarea
browser:load ✅ PASS
browser:session_refresh ✅ PASS (page reloads without crash)
window.aiui.openSessionSearch() ✅ PASS (API exposed before plugin failure path)

Playwright command output (2026-06-26)

[FAIL] chromium:ctrl_k_palette - palette not found after Ctrl+K and JS fallback
[PARTIAL] chromium:chat_input - chat page without input
[FAIL] browser:chat_input - no textarea found

Browser console (exact capture from Playwright, Chromium @ :8082)

[AIUI] Failed to load plugin "dashboard": NotFoundError: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
    at buildDashboard (http://127.0.0.1:8082/plugins/dashboard.js?v=1782452566208:1308:41)
    at async Object.init (http://127.0.0.1:8082/plugins/dashboard.js?v=1782452566208:1233:3)
    at async loadPlugin (http://127.0.0.1:8082/plugins/plugin-loader.js?v=1782451154:39:9)
    at async Promise.allSettled (index 1)
    at async HTMLDocument.main (http://127.0.0.1:8082/plugins/plugin-loader.js?v=1782451154:116:7)

(Same message repeated on each page reload during the E2E run.)

HTTP / API (unaffected)

REST chat APIs work independently (POST /api/chat/send → 200). This is a frontend-only initialization failure.

WebSocket

Not applicable to this bug (API streaming verified separately).


Expected Result

  1. buildDashboard() completes without throwing.
  2. initCommandPalette() runs; Ctrl+K opens .db-cmdk-overlay.
  3. Chat view mounts #chat-input textarea after navigating to Chat page.
  4. No [AIUI] Failed to load plugin "dashboard" in console.
  5. Playwright regression tests pass for Ctrl+K and chat input visibility.

Impact Assessment

Dimension Assessment
Technical Dashboard plugin init aborts; dependent UI hooks skipped
User No keyboard palette; no in-browser chat compose
Developer False negative on competitive gap closure (#103); E2E flakes
Business Dashboard-style ops UX degraded vs OpenClaw/Hermes
Regression Feature code present but unreachable — worse than missing feature
Performance None (fail-fast on load)
Security None direct
Accessibility Keyboard navigation (Ctrl+K) broken
Compatibility Reproduced Chromium + Edge on Windows; likely all engines

Root Cause Analysis

Architectural cause

buildDashboard() constructs the shell DOM in an order that violates the DOM insertBefore(newNode, referenceNode) contract: referenceNode must already be a child of the parent (root).

When renderSlot('shell:header', shellHeader) injects children, the code attempts to insert the header before main, but main is only appended on the next line.

Affected modules

Module Role
templates/frontend/plugins/dashboard.js buildDashboard(), initCommandPalette(), slot rendering
templates/frontend/plugins/plugin-loader.js Catches plugin init failure
templates/frontend/plugins/views/chat.js Never mounts #chat-input when plugin init fails

Why previous fixes did not prevent this


Architecture Analysis

Current architecture (failure)

flowchart TB
  subgraph Browser
    PL[plugin-loader.js] --> INIT[dashboard.init]
    INIT --> BUILD[buildDashboard]
    BUILD --> SIDEBAR[appendChild sidebar]
    BUILD --> HEADER[renderSlot shell:header]
    HEADER --> INS[insertBefore header before main]
    INS --> FAIL[NotFoundError]
    FAIL --> ABORT[Plugin load failed]
    ABORT --> SKIP[initCommandPalette SKIPPED]
    ABORT --> CHAT[chat.js view SKIPPED]
  end
Loading

Sequence diagram (error flow)

sequenceDiagram
  participant PL as plugin-loader
  participant DB as dashboard.js
  participant DOM as document #db-root
  participant CP as initCommandPalette

  PL->>DB: init()
  DB->>DB: buildDashboard()
  DB->>DOM: appendChild(sidebar)
  DB->>DB: renderSlot(shell:header) → children added
  DB->>DOM: insertBefore(shellHeader, main)
  Note over DOM: main NOT child of root yet
  DOM-->>DB: NotFoundError
  DB-->>PL: throw
  PL->>PL: log plugin failed
  Note over CP: never called
Loading

Expected / corrected architecture

flowchart TD
  BUILD[buildDashboard] --> A[appendChild main to root FIRST]
  A --> B{shell:header has children?}
  B -->|yes| C[insertBefore shellHeader before main]
  B -->|no| D[skip header insert]
  C --> E[initCommandPalette]
  D --> E
  E --> F[selectPage + view modules]
  F --> G[chat.js mounts #chat-input]
Loading

State diagram

stateDiagram-v2
  [*] --> Loading
  Loading --> PluginFailed: insertBefore throws
  Loading --> Ready: buildDashboard OK
  PluginFailed --> PartialShell: sidebar may render
  PartialShell --> NoChat: chat view absent
  PartialShell --> NoPalette: Ctrl+K inert
  Ready --> ChatReady: Chat page + textarea
  Ready --> PaletteReady: Ctrl+K works
Loading

API Analysis

Endpoint Impact
GET /api/pages ✅ Unaffected — sidebar built from API before crash in some paths
POST /api/chat/send ✅ Works — backend independent
GET /api/chat/history/{id} ✅ Works
WebSocket /api/chat/ws ✅ Works — UI cannot consume events

No API contract change required; fix is client-side DOM ordering.


UI Analysis

Surface State Recovery
Dashboard shell Partial Reload does not recover
Sidebar navigation May work Clicks do not mount chat compose
Chat page Broken empty No #chat-input
Ctrl+K palette Missing No overlay
Agents page Loads list Create/edit forms not fully exercised
Loading state Stuck partial No error banner shown to user
Error state Console only No user-visible failure message
Accessibility Ctrl+K shortcut dead Screen reader users lose quick nav

Tables

Environment matrix

OS Browser Server Reproduced
Windows 10 Chromium (Playwright) :8082
Windows 10 Edge :8082
Windows 10 Chromium :8083
Firefox Not tested
Safari Not tested
Linux Not tested (DOM bug likely cross-platform)

Browser matrix

Feature Chromium Edge
Dashboard load
Console error
Ctrl+K
Chat textarea

Severity matrix

Stakeholder Severity
End user Major
Operator Major
Developer Major

Risk matrix

Risk Likelihood Impact
Production dashboard broken High High
Silent partial UI High Medium

Regression matrix

Prior issue Relationship
#103 Enhancement closed — distinct runtime bug
#154 B-02 Gap audit — code now present, broken

Affected modules

  • dashboard.js (primary)
  • plugin-loader.js (error surfacing)
  • views/chat.js (downstream)

Validation evidence

Captured 2026-06-26 @ commit 0b62e7d. Source: Playwright run_browser_e2e.py / run_llm_browser_e2e.py stdout and console_errors in browser-e2e/artifacts/e2e-results.json.

Confidence: 100%


Suggested Fix

Primary fix (DOM ordering)

// Append main first so it is a valid reference node
root.appendChild(main);
const shellHeader = document.createElement('div');
shellHeader.id = 'db-shell-header-slot';
renderSlot('shell:header', shellHeader);
if (shellHeader.children.length) {
  root.insertBefore(shellHeader, main);
}

Alternative: insert header before sidebar or use main.prepend() pattern — choose one consistent shell layout contract.

Validation

  • Add Playwright test: load dashboard → assert no console error matching insertBefore.
  • Add Playwright test: Ctrl+K → .db-cmdk-overlay visible.
  • Add Playwright test: Chat page → #chat-input visible.

State management

  • Wrap buildDashboard() in try/catch; set window.__AIUI_DASHBOARD_ERROR__ for diagnostics.

UI rendering

  • Show user-visible error banner if plugin init fails (fail loud, not silent partial).

Error handling / logging

  • plugin-loader.js: surface init failure in UI toast, not console-only.

Testing

  • Unit: jsdom test for DOM append order with mocked slots.
  • Integration: 15-dashboard-test + 18-full-chat smoke.

Documentation

  • Document shell slot DOM contract in AGENTS.md or dashboard plugin README.

Performance / security

  • No change expected.

Acceptance Criteria

  • Bug fixed — no insertBefore NotFoundError on dashboard load
  • Ctrl+K opens command palette (Chromium + Edge verified)
  • Chat page shows #chat-input textarea
  • Playwright regression tests added and passing
  • Unit/jsdom test for buildDashboard DOM order
  • Integration test on 15-dashboard-test example
  • Browser verified on Chromium + Edge
  • Cross-browser (Firefox) — follow-up when Playwright installed
  • Documentation updated (shell slot ordering)
  • No regressions in sidebar navigation, mobile nav, approval modal

Priority

High

Dashboard is the primary operator UI path for style: dashboard. Plugin init failure blocks multiple shipped features (palette, chat compose).


Severity

Major

Core navigation and chat UX broken in browser despite working APIs.


Suggested GitHub Labels

bug, regression, frontend, dashboard, ui, windows, needs-investigation


Why This Matters

  • Engineering: Silent partial init masks failures; E2E must gate plugin load.
  • Architecture: Dashboard.js is the ops plane — its init must be atomic.
  • UX: Operators expect Ctrl+K and chat to work when APIs respond.
  • Maintainability: Slot system needs documented DOM ordering rules.
  • Reliability: Same bug blocks LLM browser validation pass entirely.
  • Technical debt: Competitive issues marked closed while runtime still broken.

Duplicate check

Check Result
GitHub open issue None
GitHub closed #103 Related enhancement — not duplicate
GitHub closed #154 Gap audit @ older SHA — not duplicate
Merged PR fix None found
Existing draft This file — expanded, not new

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions