tinyhumansai/openhuman · error · Error
"{key}" is required
Error message
"{key}" is required What it means
Reconfigure validation in InstalledServerDetail: before calling mcpClientsApi.updateEnv, every key in visibleEnvKeys must have a non-empty trimmed value in reconfigValues. The check is strict because update_env has replace-all semantics (DELETEs all env rows then INSERTs the submitted set) - a blank value would silently strip required env on the next reconnect. Throws the localized 'mcp.install.missingRequired' with {key} substituted.
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 7491200858)
Solutions
- Enter a value for the exact key named in the message, then Save again
- If the var is genuinely optional, remove it from the server's env keys so it is not part of the replace-all set, rather than submitting it blank
- Copy the full original value from the server's configuration before reconfiguring
Example fix
// before - throws only inside the busy handler after Save is clicked
for (const key of visibleEnvKeys) {
if (!reconfigValues[key]?.trim()) {
throw new Error(t('mcp.install.missingRequired').replace('{key}', key));
}
}
// after - also disable Save up front so the error cannot happen
const reconfigInvalid = visibleEnvKeys.some(k => !reconfigValues[k]?.trim());
// <Button disabled={reconfigInvalid || busy}>Save</Button> Defensive patterns
Strategy: validation
Validate before calling
// Run the identical check before opening the busy path
const invalidKeys = visibleEnvKeys.filter(k => !reconfigValues[k]?.trim());
const canSave = invalidKeys.length === 0;
// <Button disabled={!canSave || busy} onClick={handleSaveReconfigure}>Save</Button> Prevention
- Remember update_env is replace-all (DELETE then INSERT): blank never means 'keep the old value'
- Prefill every existing key's value when opening the Reconfigure dialog so users edit rather than re-enter
- Disable Save while any visible key is empty - the throw exists for races, not as the primary UX
When it happens
Trigger: Saving the Reconfigure dialog with any visible env field left empty or whitespace-only - e.g. the user clears a value intending to 'keep it as-is', or a prefill did not populate one key.
Common situations: Users assume blank means 'unchanged' (it means 'delete this var' server-side, hence the guard); migrating a server whose stored env keys have no values; copying a .env block where one line lost its value.
Related errors
- Recovery phrase is required.
- Invalid ${paramName}: ${value}. Must be a positive integer.
- Invalid ${paramName}: '${value}'. Must be a positive integer
- Invalid ${paramName}: ${String(value)}. Must be a positive i
- mascot manifest: missing mascots array
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/29509e39b44be128.
Report an issue: GitHub.