Skip to content

[BUG][UI]: 'Add LLM Provider' and 'Add LLM Model' modals silently fail — onsubmit references undefined globals #4619

@meltforce

Description

@meltforce

Summary

Two modals on /admin/#llm-settings silently fail when clicking the Save button: Add LLM Provider (Providers tab) and Add LLM Model (Models tab). In both cases the modal closes, no provider/model is added, no error toast, no log line — nothing observable.

Root cause

mcpgateway/templates/admin.html has two <form> elements whose inline onsubmit references a bare global, but the bundled admin JS only exposes those handlers under the Admin namespace:

Line Current Should be
2081 <form id="llm-provider-form" onsubmit="saveLLMProvider(event)"> <form id="llm-provider-form" onsubmit="Admin.saveLLMProvider(event)">
2179 <form id="llm-model-form" onsubmit="saveLLMModel(event)"> <form id="llm-model-form" onsubmit="Admin.saveLLMModel(event)">

admin.js registers both as Admin.saveLLMProvider = saveLLMProvider / Admin.saveLLMModel = saveLLMModel, but neither is exposed as a window global. The bare reference therefore raises ReferenceError. With no return value preventing default, the form falls back to a normal browser submit → GET . → page silently re-renders → modal disappears, nothing is POSTed.

The same template uses onchange="Admin.onLLMProviderTypeChange()" / onchange="Admin.onModelProviderChange()" on the lines right next to these forms, which is consistent with how the bundle actually exposes these functions. Only the onsubmit calls were missed.

A quick scan of the rest of admin.html confirms these are the only two cases: every other inline handler (toggleBulkImportDropdown, submitUserInvitation, closeCreateTeamModal, …) refers to a function that is a real window global. Only saveLLMProvider / saveLLMModel are namespace-mismatched.

Reproduction

  1. Run ghcr.io/ibm/mcp-context-forge:1.0.0 (or latest / main).
  2. Sign in as the platform admin.
  3. Navigate to /admin/#llm-settings.

Provider:
4. Click Add Provider, fill Name + select Anthropic + paste any API key.
5. Click Save Provider.

Model (after a provider exists):
6. Switch to Models tab, click Add Model, pick the provider, fill Model ID + Display Name.
7. Click Save Model.

Expected: POST /llm/providers (or /llm/models) → 201 Created; entity appears in the list.

Actual: Modal closes, no network request fires, "0 Total" remains.

DevTools confirmation:

> typeof window.saveLLMProvider          // "undefined"
> typeof window.Admin.saveLLMProvider    // "function"
> typeof window.saveLLMModel             // "undefined"
> typeof window.Admin.saveLLMModel       // "function"
> new Function('event','saveLLMProvider(event)')(new Event('submit'))
   Uncaught ReferenceError: saveLLMProvider is not defined

Fix

Two-line template change (PR follows): namespace both onsubmit calls.

-              <form id="llm-provider-form" onsubmit="saveLLMProvider(event)">
+              <form id="llm-provider-form" onsubmit="Admin.saveLLMProvider(event)">
...
-              <form id="llm-model-form" onsubmit="saveLLMModel(event)">
+              <form id="llm-model-form" onsubmit="Admin.saveLLMModel(event)">

Workaround (verified locally)

Bind-mount a patched admin.html with the two lines above. After that, both Save Provider and Save Model correctly fire POST /llm/providers / POST /llm/models → 201.

Affected versions

  • v1.0.0 (GA, 2026-05-01) — confirmed
  • main HEAD — same lines, same bug

Environment

  • Container: ghcr.io/ibm/mcp-context-forge:latest (currently == v1.0.0)
  • Browser: Chrome (any), but the bug is a server-side template issue, not browser-specific.
  • Auth: PLATFORM_ADMIN user, all RBAC routers loaded normally.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions