// Public Ledger
Known Issues
"These are the things we know about. You deserve to know too — and you deserve to know before you have to call us. Every open issue below is real, current, and being worked. Where a workaround exists, it is linked. Resolved issues stay on this page because the trajectory matters as much as the current state. We are called candor. This page is why."
Open
15 active
Auto-created RMM tickets hardcode brand/site
MULTI-TENANT LANDMINE (PSA-20): ninja-inbound hardcodes p_brand_key='SR' and p_site_code='SA' in its get_next_document_number call for auto-created tickets. Works only because SummitRidge is the sole tenant; any other tenant's NinjaOne auto-tickets will fail numbering or misnumber under a foreign brand. Fix belongs to PSA-20 multi-tenant pass: resolve brand/site from tenant_branding (default brand) at runtime.
Linked: Marketplace / NinjaOne Integration
Walk-in Coach™ alerts never fire on Service Desk
Service Desk board fails: 'column coach_alerts.urgency does not exist'. Real column (verified via information_schema) is urgency_state. LATENT DEFECT: the board's coach_alerts query has referenced 'urgency' since the Service Desk was first built — meaning walk-in Coach alerts and the amber attention banner have NEVER worked; the failure was silently swallowed until BUILD 4's error surfacing exposed it. BUILD 4 revealed this bug, it did not cause it.
Linked: Service Desk / Coach Alerts
Service Desk board load error (checkout linkage)
Service Desk board fails to load: 'column tickets.checkout_invoice_id does not exist'. Introduced by the BUILD 3 checkout→invoice rework — the Lovable-generated code selects/writes tickets.checkout_invoice_id, a column that was never created (the RPC design links invoices to tickets via invoices.ticket_id and did not add a ticket-side pointer). Notably: the error was caught and displayed by BUILD 4's new board error state (inline message + Retry + copyable toast) — the silent-failure fix surfaced its sibling build's defect immediately, as designed.
Linked: Service Desk / Checkout→Invoice (BUILD 3)
Script images don't render during scene playback
Script images do not render during scene playback. Jerry performed 'talent_show_origin' (the ventriloquist epic) via Script Director™ Perform in the Water Cooler — the two image lines (kitty-puppet.png mid-rant, kitty-is-pissed.png finale) never appeared. The images build added image rendering, but the synthesized scene-playback path (ambient + Director Perform) is evidently not rendering lines carrying image_url — likely skipping empty-text image-only lines as 'empty', or the image bubble renderer is wired only to real chat_messages rows (context_data.image_url) and not to synthesized script lines.
Linked: Water Cooler / Chat Images / Script Director™
Agents don't reply to human messages in the Water Cooler
Human messages in the Water Cooler get zero agent response — total silence. Typed 'What is going on here?' → crickets forever. Intended behavior (Jerry's spec): NEVER silence — work-shaped messages get claimed/dispatched by the right agent; joke riffs get up to 30 on-the-fly Haiku replies from rotating in-character agents, then M's verbatim cutoff. The watercooler-responder governor exists and is deployed; something in the invoke path or its gates is eating every message.
Linked: Water Cooler / Banter Governor
New DM conversations fail on first message
Starting a NEW DM conversation in Messages and sending the first message fails with 'invalid input syntax for type uuid: dm:{userId}-{userId}:{timestamp}'. Root cause: the New DM flow mints a composite string session id and inserts it into chat_messages.session_id (uuid, FK → chat_sessions.id). DMs never create a chat_sessions row at all. Same defect family as BUG-019/021.
Linked: Messages / Chat System
Room messages fail to send
Sending any message into the Water Cooler room fails with 'invalid input syntax for type uuid'. ROOT CAUSE (schema-level, shared with BUG-019): chat_messages.session_id is typed uuid, but rooms/banter/agent-composite flows insert string session ids ('room:water-cooler:{tenantId}', 'agent:BUREAU:{tenantId}'). Every such insert fails the uuid cast. Consequence: Bureau Banter™ emission has been silently failing since deployment (fire-and-forget swallowed the error) — zero banter rows ever persisted. Fix direction: rooms use chat_rooms.id (uuid) as session_id; all composite string ids become lookups/aliases, never inserted values.
Linked: Messages / Chat System / Bureau Banter™
Team Members list renders empty
Messages sidebar Team Members section renders empty despite 4 active users existing for the tenant. Root cause identified via direct DB inspection: public.users has 4 rows for the tenant, public.user_presence has 0 rows — the Team Members query drives from (or inner-joins) user_presence, so an empty presence table yields an empty roster. Presence must decorate the list (LEFT JOIN, missing = offline), never gate it.
Linked: Messages / Chat System
New FELIX™ chat session fails on first send
FELIX™ panel 'New' chat session fails on first send — toast error 'invalid input syntax for type UUID'. Creating a new chat session and sending a first message (e.g. 'Are you alive?') triggers a Postgres UUID cast failure, suggesting a non-UUID value (likely an agent-style session string or a client-generated id) is being inserted into a uuid-typed column, or a nullable uuid field is receiving a malformed placeholder.
Linked: FELIX™ Panel / Chat Sessions
Dashboard card area disagrees with ticker
Helix Dash™ card area shows 'No items in flight' while the Dash ticker simultaneously displays live in-flight items (e.g. 'audit, email was hacked — 1249 min overdue'). The ticker and the card grid are reading from divergent queries — one returns the items, the other returns empty. Suspected causes: mismatched brand filter, status enum mismatch, tenant scoping difference, or the two surfaces querying different tables/views.
Linked: Helix Dash™
Invoice status doesn't auto-set to Sent on email
Invoice status does not automatically update to 'Sent' when an invoice is emailed to the client. Expected behavior: sending an invoice via email should transition the invoice status from Draft/Open to Sent automatically.
Linked: PSA-8: Invoicing
Print button missing on three pages
Print button missing on Items to be Billed page, Account Management page, and Documents page. Per standing rule, every page requires a printer icon button and Command Bar 'Print This' support. These three pages were built without it.
Linked: PSA-15: Settings & Administration
Company filter missing on list pages
Company filter dropdown is missing on Tickets, Projects, Invoices, Proposals, and Contracts list pages. The filter bar exists but the company/client filter option has not been implemented on these pages.
Linked: PSA-3: Ticketing System
AI Assist button silent on invoice line items
AI Assist button on invoice line items fails silently. Clicking the AI button on a line item in the invoice editor produces no response and no visible error state.
Linked: PSA-8: Invoicing
Invoice list shows stale totals
Invoice list page shows stale total amounts after an invoice is updated. The total column does not refresh after a create, update, or line-item change — requires a full page reload to reflect the correct amount.
Linked: PSA-8: Invoicing
Recently Resolved
17 resolved
Signature verification bypassable when header omitted
SECURITY: ninja-inbound verifies HMAC only when a signature header is present — omitting X-Ninja-Signature/X-NinjaRMM-Signature bypasses verification entirely and the request is processed (tickets, Coach alerts, asset updates). Enforcement was left conditional in case NinjaOne genuinely sends unsigned events; must be confirmed and enforced in the same fix pass as BUG-030. KNOWN GAP comment added at file header and inline at the HMAC block (v2).
Linked: Marketplace / NinjaOne Integration
Webhook signature verification missing
SECURITY: ninja-webhook NEVER verifies HMAC. It fetches webhook_secret from credentials and never uses it — no signature check of any kind. Anyone who knows a tenant UUID can POST fabricated NinjaOne events that create tickets, fire Coach™ alerts, and dispatch NIGHTSHADE™ bureau assignments (which invoke remediator-processor). KNOWN GAP comment added in code at getCredentials (v6); behavior intentionally unchanged during the instance-aware pass per byte-for-byte doctrine. Needs its own fix pass with a grace window so live NinjaOne traffic is not locked out mid-cutover.
Linked: Marketplace / NinjaOne Integration
RMM sync config reads never worked
ninja-sync v6 writeHelixUrls was DEAD CODE from /run and its config reads never worked: the old get_ninja_credentials RPC did not return helix_base_url / ninja_cf_helix_client_url / ninja_cf_helix_asset_url, so (1) runSync's guard if(creds.helix_base_url) was always false — writeHelixUrls never executed from /run; (2) when invoked via /write-helix-urls, all three reads were undefined and hardcoded fallbacks always won, ignoring tenant configuration. Bonus defect: writeHelixUrls double-loaded creds with no instance context.
Linked: Marketplace / NinjaOne Integration
Integration backfill silently matched nothing
PASS A qbo_connections backfill migration targeted integration_key 'quickbooks_online' but the canonical marketplace catalog key is 'quickbooks'. The backfill matched ZERO rows and linked nothing — silent no-op. Root cause: key written from memory instead of verified against the live catalog. Spawned STANDING CHECK: every backfill/panel query verifies integration_key against live catalog first, never from memory.
Linked: Marketplace / QuickBooks Online
Wizard teaching copy never rendered
CreationWizard queried nonexistent column step_order on wizard content tables (real column: sort_order). Query silently errored on EVERY wizard open since the wizard was built, so all data-driven teaching copy (scenarios, ceremony rows) never rendered — hardcoded fallbacks always won. LATENT DEFECT exposed during PSA-54X pass; the wizard appeared to work because fallbacks masked the failure.
Linked: Marketplace / Creation Wizard
Ticket rows too large
Ticket list rows were too large — only 3-5 tickets visible without scrolling on a 1080p monitor, making the queue unusable for a busy MSP.
Linked: PSA-3: Ticketing System
Tech column showed email instead of name
Assigned tech column on the Tickets list page was showing the tech's email address instead of their first name.
Linked: PSA-3: Ticketing System
Proposal generation produced a contract
Proposal creation was not filtering by document_type = proposal — copied all 53 templates (17 proposal + 36 contract) into proposal_clauses, causing Generate Document to produce a service contract instead of a proposal.
Linked: PSA-6: Proposals & Takeoffs
Coach™ alert panel wrong position
The Coach™ alert panel appears in the wrong position on the screen, overlapping other UI elements. Position needs to be corrected to its intended bottom-right placement without obscuring the Command Bar™ or other floating widgets.
Linked: The Coach™
Test emails weren't logged
Test Connection emails were not being logged to the email_notifications table — test sends were invisible in the email log, making it impossible to confirm whether tests actually sent.
Linked: PSA-15: Settings & Administration
Email test sent plain text
Test Connection sent a plain text email instead of the branded HTML that clients actually receive — meaning the test was not showing what the client would see.
Linked: PSA-15: Settings & Administration
Email test failure showed no reason
Test Connection failed toast showed no reason for failure — the toast said 'Test Failed' but did not surface the actual Resend error message, making the problem impossible to diagnose.
Linked: PSA-15: Settings & Administration
Email test fired before save
Email Settings Test Connection button fires before Save — button was active even when the Resend API key field had unsaved changes or was empty, causing a test against a key that was not yet persisted.
Linked: PSA-15: Settings & Administration
Browser tab title showed company name
Chrome browser tab showed the company name as the page title instead of the current route/view name.
Linked: PSA-0: Database Foundation Schema
Print template said WORK ORDER instead of TICKET
Printed ticket output displayed 'WORK ORDER' instead of 'TICKET' on all print templates.
Linked: PSA-3: Ticketing System
Command Bar™ history showed only last command
Command Bar history panel shows only the last executed command instead of the full history list. The history dropdown/panel is not accumulating entries across the session.
Linked: Command Bar™ Intelligence Layer
Command Bar™ line total calculated as zero
Command Bar line_total calculates as 0 on parts order cards. The line total field is not being computed correctly when a part is resolved and quantity confirmed via the Command Bar™ — the card shows $0.00 instead of qty * unit_price.
Linked: Command Bar™ Intelligence Layer