tinyhumansai/openhuman · warning

mcp.install.missingRequired

Error message

mcp.install.missingRequired

What it means

Reconfigure uses replace-all semantics — updateEnv DELETEs then INSERTs every env row — so every visible env key must carry a value or the server would come back up missing required credentials. The save handler validates each reconfigValues[key] and throws this message (with {key} substituted) before any RPC is sent.

Source

Thrown at app/src/components/channels/mcp/InstalledServerDetail.tsx:199

  // sets may be partial; the form requires every key so a reconnect never drops
  // a required var (issue #3039 gap B6 — suggested values were never persisted).
  const handleApplySuggestedEnv = useCallback(
    (env: Record<string, string>) => {
      log('suggested_env received, opening reconfigure form keys=%o', Object.keys(env));
      setShowAssistant(false);
      openReconfigure(env);
    },
    [openReconfigure]
  );

  const handleSaveReconfigure = useCallback(() => {
    void runBusy(async () => {
      // Replace-all semantics (update_env DELETEs then INSERTs): every key must
      // have a value or the server loses required env on reconnect. Mirror the
      // install dialog's validation.
      for (const key of visibleEnvKeys) {
        if (!reconfigValues[key]?.trim()) {
          throw new Error(t('mcp.install.missingRequired').replace('{key}', key));
        }
      }
      log('reconfigure save server_id=%s', server.server_id);
      const result = await mcpClientsApi.updateEnv({
        server_id: server.server_id,
        env: reconfigValues,
      });
      setTools(result.tools ?? []);
      if (result.status === 'unauthorized') {
        // A 401 after reconfigure: show the actionable auth reason (use Sign in
        // / token rejected / credential required) the same way the Connect
        // dialog does — the raw 401 message is withheld server-side (#4289).
        const key = authHintMessageKey(result.auth_hint);
        throw new Error(key ? t(key) : t('mcp.detail.reconfigureReconnectFailed'));
      }
      if (result.status !== 'connected') {
        throw new Error(result.error ?? t('mcp.detail.reconfigureReconnectFailed'));
      }

View on GitHub (pinned to a221052e0d)

Solutions

  1. Fill every required field with its credential value and save again — the error names the missing key
  2. If a key is genuinely obsolete, remove it by reinstalling/reconfiguring the server's declared env, never by blanking it
  3. Trim accidental whitespace before saving

Example fix

// before (lets updateEnv strip required env)
await mcpClientsApi.updateEnv({ server_id, env: reconfigValues });

// after (validate replace-all input first)
for (const key of visibleEnvKeys) {
  if (!reconfigValues[key]?.trim()) {
    throw new Error(t('mcp.install.missingRequired').replace('{key}', key));
  }
}
await mcpClientsApi.updateEnv({ server_id, env: reconfigValues });
Defensive patterns

Strategy: validation

Validate before calling

// Disable Save until every required env key is non-empty:
const canSave = visibleEnvKeys.every(k => (reconfigValues[k] ?? '').trim().length > 0);
<Button disabled={!canSave} ...>

Type guard

const hasAllEnvValues = (
  keys: readonly string[],
  values: Record<string, string | undefined>
): boolean => keys.every(k => !!values[k]?.trim());

Prevention

When it happens

Trigger: Clicking Save in the reconfigure dialog with one or more env fields left blank or whitespace-only; the thrown message names the exact offending key.

Common situations: User clears a field intending to remove it (not supported — the key set is fixed by the server's declared env_keys); pasted values that are only spaces.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/b4ba167b9d4462f4. Report an issue: GitHub.