Skip to content

frontend: 77 dead UI calls hit non-existent backend routes (browser automation, dev-speedup, code-intelligence, knowledge_base) — audit_api_wiring.py reports 0 because it can't see getApiBase() paths #12326

Description

@mrveiss

Summary

77 distinct frontend API calls hit paths no backend route serves. Every one is a UI control that renders normally and fails when used — dead buttons and panels that error, across 30 frontend files.

Each was verified live against the running deployment: 404 on both GET and POST. False positives from path normalisation (query-string artifacts, trailing-slash redirects) were tested and excluded — 14 candidates were dropped this way.

The repo's own audit gate cannot see any of this

scripts/audit_api_wiring.py reports a clean bill:

$ python3 scripts/audit_api_wiring.py --openapi openapi.json
mode: AUTHORITATIVE (openapi)
backend paths: 2150 | frontend distinct /api/ paths: 208

== UNWIRED FRONTEND CALLS: 0 ==
== getBackendUrl() CALLS MISSING /api: 0 ==
== UNMOUNTED ROUTER MODULES: 0 ==

Zero findings — while 77 calls are broken. The script matches literal /api/... strings, but the dominant idiom in this codebase composes the path from a helper:

apiClient.get<DocCategoriesResponse>(`${getApiBase()}/knowledge_base/system-docs/categories`)

Counting distinct occurrences in autobot-frontend/src:

idiom distinct paths seen by audit
literal '/api/...' 361 yes
`${getApiBase()}/...` 500 no
`${getBackendUrl()}/...` 19 partially

So the gate inspects roughly 42% of calls and is blind to the majority. This is the highest-value fix in this issue — without it, every finding below can silently regress.

Confirmed dead paths, grouped by feature

/knowledge_base — 11 dead

frontend call called from
/knowledge_base/category/{p} composables/knowledge/useKnowledgeCategories.ts:130
/knowledge_base/connectors/oauth/{p} models/repositories/KnowledgeRepository.ts:704
/knowledge_base/documents/{p} models/repositories/KnowledgeRepository.ts:450
/knowledge_base/documents/{p}/similar models/repositories/KnowledgeRepository.ts:489
/knowledge_base/facts/{p} models/repositories/KnowledgeRepository.ts:459
models/repositories/KnowledgeRepository.ts:468
/knowledge_base/health models/repositories/KnowledgeRepository.ts:537
/knowledge_base/suggestions models/repositories/KnowledgeRepository.ts:515
/knowledge_base/system-docs/categories composables/knowledge/useKnowledgeSystemDocs.ts:66
/knowledge_base/system-docs/category/{p} composables/knowledge/useKnowledgeSystemDocs.ts:73
/knowledge_base/system-docs/{p} composables/knowledge/useKnowledgeSystemDocs.ts:81
/knowledge_base/verification/{p} models/repositories/KnowledgeRepository.ts:586
models/repositories/KnowledgeRepository.ts:601

/browser — 9 dead

frontend call called from
/browser/automation/run composables/useBrowserAutomation.ts:310
/browser/click composables/useBrowserAutomation.ts:253
/browser/close composables/useBrowserAutomation.ts:183
/browser/execute composables/useBrowserAutomation.ts:296
/browser/launch composables/useBrowserAutomation.ts:167
/browser/navigate composables/useBrowserAutomation.ts:238
/browser/screenshot composables/useBrowserAutomation.ts:281
/browser/session/{p} composables/useBrowserAutomation.ts:223
composables/useBrowserAutomation.ts:324
/browser/type composables/useBrowserAutomation.ts:267

/dev-speedup — 8 dead

frontend call called from
/dev-speedup/boilerplate composables/useDevSpeedup.ts:162
/dev-speedup/format composables/useDevSpeedup.ts:209
/dev-speedup/lint-fix composables/useDevSpeedup.ts:225
/dev-speedup/optimize composables/useDevSpeedup.ts:193
/dev-speedup/quick-search composables/useDevSpeedup.ts:98
/dev-speedup/refactor-suggest composables/useDevSpeedup.ts:147
/dev-speedup/snippet-generate composables/useDevSpeedup.ts:113
/dev-speedup/test-generate composables/useDevSpeedup.ts:178

/system — 8 dead

frontend call called from
/system/backup/create models/repositories/SystemRepository.ts:353
/system/backup/list models/repositories/SystemRepository.ts:358
/system/backup/restore/{p} models/repositories/SystemRepository.ts:363
/system/backup/{p} models/repositories/SystemRepository.ts:368
/system/health/probes composables/useHealthProbeRegistry.ts:49
/system/restart models/repositories/SystemRepository.ts:270
/system/shutdown models/repositories/SystemRepository.ts:276
/system/updates/check models/repositories/SystemRepository.ts:387

/code-intelligence — 6 dead

frontend call called from
/code-intelligence/analysis/{p} composables/useCodeIntelligence.ts:194
composables/useCodeIntelligence.ts:324
/code-intelligence/batch-analyze composables/useCodeIntelligence.ts:341
/code-intelligence/compare composables/useCodeIntelligence.ts:293
/code-intelligence/history composables/useCodeIntelligence.ts:309
/code-intelligence/quality-score composables/useCodeIntelligence.ts:211
/code-intelligence/trends composables/useCodeIntelligence.ts:278

/api — 3 dead

frontend call called from
/api/heartbeat components/agents/HeartbeatPanel.vue:314
/api/transcriber/recordings/{p}/progress composables/transcriber/useSseProgress.ts:17
/api/user-management/users/{p}/{p} views/AdminUsersView.vue:438

/tls — 3 dead

frontend call called from
/tls/credentials/{p} composables/useTLSCredentials.ts:273
composables/useTLSCredentials.ts:301
/tls/endpoints composables/useTLSCredentials.ts:342
/tls/expiring composables/useTLSCredentials.ts:361

/advanced-control — 2 dead

frontend call called from
/advanced-control/takeover/sessions/{p} utils/AdvancedControlApiClient.ts:332
utils/AdvancedControlApiClient.ts:345
/advanced-control/takeover/{p} utils/AdvancedControlApiClient.ts:318

/batch-schedules — 2 dead

frontend call called from
/batch-schedules composables/useBatchProcessing.ts:142
composables/useBatchProcessing.ts:152
/batch-schedules/{p} composables/useBatchProcessing.ts:162
composables/useBatchProcessing.ts:172

/batch-templates — 2 dead

frontend call called from
/batch-templates composables/useBatchProcessing.ts:112
composables/useBatchProcessing.ts:122
/batch-templates/{p} composables/useBatchProcessing.ts:132

/cost — 2 dead

frontend call called from
/cost/by-agent components/analytics/AgentCostPanel.vue:195
/cost/by-agent/{p}/budget components/analytics/AgentCostPanel.vue:222

/knowledge — 2 dead

frontend call called from
/knowledge/search composables/useApi.ts:336
/knowledge/verification/approve components/knowledge/KnowledgeResearchPanel.vue:318

/nodes — 2 dead

frontend call called from
/nodes composables/useTLSCredentials.ts:196
/nodes/{p}/tls-credentials composables/useTLSCredentials.ts:221
composables/useTLSCredentials.ts:245

/agent-terminal — 1 dead

frontend call called from
/agent-terminal/tasks/{p} services/LiveEventService.ts:315

/analytics — 1 dead

frontend call called from
/analytics/bug-prediction composables/analytics/useBugPrediction.ts:31

/auth — 1 dead

frontend call called from
/auth utils/ApiClient.ts:354

/batch-jobs — 1 dead

frontend call called from
/batch-jobs/{p}/cancel composables/useBatchProcessing.ts:92

/conversation-files — 1 dead

frontend call called from
/conversation-files/conversation/{p} composables/useConversationFiles.ts:112

/errors — 1 dead

frontend call called from
/errors composables/useErrorMonitoring.ts:192

/knowledge-graph — 1 dead

frontend call called from
/knowledge-graph composables/useKnowledgeGraph.ts:145

/multimodal — 1 dead

frontend call called from
/multimodal/health utils/VisionMultimodalApiClient.ts:493

/playwright — 1 dead

frontend call called from
/playwright components/desktop/PopoutChromiumBrowser.vue:527

/rebuild_index — 1 dead

frontend call called from
/rebuild_index models/repositories/KnowledgeRepository.ts:529

/research — 1 dead

frontend call called from
/research/comprehensive services/api.ts:144

/sandbox — 1 dead

frontend call called from
/sandbox/files composables/useFileSandbox.ts:57

/service-monitor — 1 dead

frontend call called from
/service-monitor/resources models/repositories/SystemRepository.ts:346
services/api.ts:263

/user — 1 dead

frontend call called from
/user/profile services/CacheService.ts:49

/vision — 1 dead

frontend call called from
/vision composables/useVisionAutomation.ts:56

/ws — 1 dead

frontend call called from
/ws services/GlobalWebSocketService.ts:146
services/GlobalWebSocketService.ts:153

/{p} — 1 dead

frontend call called from
/{p} services/CacheService.ts:107

Notable clusters

  • /browser (9 dead) — the entire browser-automation control surface (launch, navigate, click, type, screenshot, execute, close, automation/run, session/{id}) is unwired. The backend does implement browser control, but only under /api/browser/mcp/* (19 routes, for agent/MCP consumption). There is no HTTP surface behind the human UI at all, so useBrowserAutomation.ts is dead end to end.
  • /dev-speedup (8 dead) — format, lint-fix, optimize, refactor-suggest, test-generate, snippet-generate, boilerplate, quick-search. The backend has 12 /api/dev-speedup/* routes, none of which are these — the panel and the API were built to different lists.
  • /code-intelligence (6 dead) — quality-score, trends, history, compare, batch-analyze, analysis/{id}, against 37 existing /api/code-intelligence/* routes. Same pattern: a real, well-populated backend, and a frontend calling names that were never part of it.
  • /knowledge_base (11 dead) — includes health, suggestions, documents/{id}, facts/{id}, and the whole system-docs/* family. Note /api/knowledge_base/facts/by_category does work, so this is not a mounting problem — individual paths drifted.

Recommendation

  1. Fix the audit script first. Teach it to resolve getApiBase() / getBackendUrl() template prefixes, then run it in CI with --fail-on-unwired. Everything else here is a consequence of that gap.
  2. Triage each cluster to decide the canonical side — most look like a frontend built against a proposed API that landed under different names, so the frontend paths are probably wrong rather than the backend being missing.
  3. Per the repo's dead-code policy these are unwired features, not deletion candidates: either wire each to its real route or feature-flag the control so the UI stops advertising it. No dead button should ship.
  4. Enforce that frontend calls derive from src/types/generated/api.ts — the generated contract already holds the correct paths for much of this.

Method

python3 scripts/audit_api_wiring.py --openapi <live openapi.json>   # 0 findings
# then, extracting getApiBase()/getBackendUrl() template paths and resolving
# each against the live route table, verifying every candidate with GET+POST

Live spec: 2150 routes from the running deployment. Frontend: autobot-frontend/src at Dev_new_gui.

Impact

High. Whole panels error on use — browser automation, dev-speedup, code-intelligence quality/trends, batch templates and schedules, TLS credentials, cost-by-agent, and the Knowledge System Docs page. The audit that exists to prevent exactly this reports clean.

Environment

install.sh deploy at /opt/autobot; deployed tree matches origin/Dev_new_gui.

Activity

  1. mrveiss commented on Jul 24, 2026

    @mrveiss
    OwnerAuthor

    Verified all 77 against the authoritative route table (app.openapi() = 2155 HTTP + 25 WS routes) in PR #12376. The premise was partly mis-diagnosed — the split is:

    Audit blind spot fixed (the issue's highest-value item): scripts/audit_api_wiring.py now resolves ${getApiBase()} -> /api. Frontend paths it can see went 208 -> 691; unwired findings 0 -> 44. Known remaining limitation: it still inspects only the autobot backend, so SLM-served calls (tls/nodes) show as unwired — SLM-backend awareness is a sensible follow-up before gating CI with --fail-on-unwired.

    Leaving this open (Refs, not Closes) until the deferred/flagged buckets are dispositioned.

  2. mrveiss commented on Jul 26, 2026

    @mrveiss
    OwnerAuthor

    Status split: the highest-value half — the api-wiring audit gate being blind to getApiBase()/backend-URL idioms — is already fixed: scripts/audit_api_wiring.py:84 (GETAPIBASE_CALL_RE) and :91 (BACKEND_URL_CALL_RE) now resolve those idioms (comments cite this issue). The remaining 77 dead UI calls persist and are heterogeneous (prefix/name mismatches vs genuinely-absent routes vs research_browser/dev-speedup routers) — each group is a per-feature product decision (rewire-to-existing / build-backend / remove-UI), tracked alongside #12378. Keeping open for that half.

  3. modified the milestones: Backlog, v0.14.0 on Sep 12, 2026
  4. mrveiss commented on Sep 27, 2026

    @mrveiss
    OwnerAuthor

    Re-measured today against the running instance after the owner reported dead buttons in codebase analytics and elsewhere. The issue holds. Five things to add, one of which is a working model for the fix that exists in this repo already.

    I filed #17611 before finding this issue — my search was for "route reachability" and missed "dead UI calls". Closing that as a duplicate; its content is below.

    Current count: 45, not 77

    Production call sites only (excluding *.test.ts, *.spec.ts, *.stories.ts and src/test/), matched against the live openapi.json with ${...} and {...} normalised:

    File Unserved paths
    composables/useDevSpeedup.ts 8
    models/repositories/SystemRepository.ts 6
    composables/useBrowserAutomation.ts 5
    composables/useCodeIntelligence.ts 5
    composables/useTLSCredentials.ts 3
    23 further files 1–2 each

    I have not established why this differs from 77 — it may be calls fixed since, a stricter exclusion of test files, or a normalisation difference. The two numbers should be reconciled before either is used for progress tracking.

    The routers are healthy — this is not load failure

    /api/health/feature-routers reports 122 loaded, 0 failed. The mount exists; the specific path does not.

    Prefix Served live Called by the frontend
    /api/code-intelligence 37 routes quality-score, trends, history, compare, batch-analyze — none served
    /api/dev-speedup 12 format, lint-fix, boilerplate — none served
    /api/browser 19, all under /mcp/ launch, close, execute, type, automation/run — none served
    /api/tls 0 three calls

    /api/tls serving zero routes is a different shape from the others — the router is absent entirely rather than the path renamed. Worth separating when this is triaged.

    The discriminator that makes triage cheap

    FastAPI matches the route before the auth gate, so on an unauthenticated probe:

    • 404 — no such route. Dead.
    • 401 — the route exists and auth fired. Wired correctly.

    That separates "never built" from "needs a session" without credentials.

    It is also how I established WorkflowBuilder is not in this set, though the owner named it: useWorkflowBuilder.ts calls seven /api/orchestrator/* paths and all seven return 401. Whatever fails there is not a missing route.

    The fix already exists — for the other GUI

    repo_tests/slm_frontend_calls_reach_served_routes_test.py asserts exactly this property for autobot-slm-frontend, and its docstring calls itself the fifth instance of the class: #15198, #15199, #15230, #15236, #15533. Its words:

    The button works, the modal opens, the request 404s, and the caller swallows it.

    It scans autobot-slm-frontend/src only. There is no equivalent for autobot-frontend/src — this issue is the sixth instance of a class already guarded in the sibling package. The remedy is to model that guard rather than to repair audit_api_wiring.py, and the SLM one documents why the OpenAPI contract alone is insufficient: FastAPI omits @router.websocket handlers from openapi.json, so the served set must be the contract unioned with WebSocket routes parsed from the backend.

    The generated contract is a usable oracle

    autobot-frontend/src/types/generated/api.ts holds 2,215 paths; the live app serves 2,219; zero contract paths are absent live. It is a faithful subset, so a guard can use it without a running backend.

    I checked this because I had assumed the opposite — that the contract was stale — after seeing code-intelligence registered in feature_routers.py while its called paths 404'd. Registration of a prefix is not service of a path, and the contract was right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions