Skip to content

Commit aa14947

Browse files
mkotelnikovclaude
andcommitted
fix(models-config): namespace input names per type + truthy error gate
Two issues survived the per-type form-state landing: 1. API Key (and Name / URL) appeared filled across all four sub-tabs even though my per-type bindings were correct. Root cause: browser autofill. All four tabs' inputs shared `name="apiKey"`, `name="name"`, `name="url"` — browsers treat same-named password / text fields as the same logical field and silently propagate stored credentials across them, so the value typed into Google was auto-filled into OpenAI / Anthropic / OpenAI-compatible regardless of what the json-render `value` binding said. The state was per-type; the DOM input was being filled by Chrome/Firefox's autofill heuristic. Fix: every Input now has a `name="${type}-${field}"` (e.g. `google-apiKey`, `openai-apiKey`, `anthropic-name`). Browsers no longer cross-pollinate values. 2. Error Alert visibility used `{ neq: null }` which evaluates `value !== null` — visible for `undefined`, `""`, and any string. If the seeded `error: null` was missing or got shadowed, the panel rendered "Error" with an empty message. Fix: switch to `{ $state: ".../error" }` (no comparator). The json-render `evaluateCondition` falls back to `Boolean(value)` when no comparator is supplied — `null`, `undefined`, and `""` all evaluate to false (hidden); only a real non-empty string makes the Alert appear. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 7ff4335 commit aa14947

1 file changed

Lines changed: 12 additions & 8 deletions

File tree

packages/models-config/src/public/connections-tab-spec.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,15 @@ function tabBodyElements(type: ConnectionType): Record<string, unknown> {
172172
type: "Heading",
173173
props: { text: "Headers", level: "h4" },
174174
},
175+
// Input `name` attributes are per-type-prefixed so the browser's
176+
// autofill heuristics don't share the value across the four
177+
// sub-tabs (otherwise the OpenAI API Key field would be
178+
// auto-filled with the value the user typed into Google).
175179
[`${type}_formName`]: {
176180
type: "Input",
177181
props: {
178182
label: "Name",
179-
name: "name",
183+
name: `${type}-name`,
180184
type: "text",
181185
placeholder: `e.g. ${TYPE_LABEL[type]} (work)`,
182186
value: { $bindState: `/ui/connectionForms/${type}/name` },
@@ -186,7 +190,7 @@ function tabBodyElements(type: ConnectionType): Record<string, unknown> {
186190
type: "Input",
187191
props: {
188192
label: "API Key",
189-
name: "apiKey",
193+
name: `${type}-apiKey`,
190194
type: "password",
191195
placeholder: "sk-…",
192196
value: { $bindState: `/ui/connectionForms/${type}/apiKey` },
@@ -196,7 +200,7 @@ function tabBodyElements(type: ConnectionType): Record<string, unknown> {
196200
type: "Input",
197201
props: {
198202
label: urlLabel,
199-
name: "url",
203+
name: `${type}-url`,
200204
type: "text",
201205
placeholder: urlPlaceholder,
202206
value: { $bindState: `/ui/connectionForms/${type}/url` },
@@ -259,11 +263,11 @@ function tabBodyElements(type: ConnectionType): Record<string, unknown> {
259263
message: { $state: `/ui/connectionForms/${type}/error` },
260264
type: "error",
261265
},
262-
// Only render when error is a non-null string. Initial state
263-
// seeds `error: null`, action handlers reset to `null` on
264-
// success, so this gate hides the panel until a real error
265-
// arrives.
266-
visible: { $state: `/ui/connectionForms/${type}/error`, neq: null },
266+
// Truthy gate — `evaluateCondition` falls back to
267+
// `Boolean(value)` when no comparator (eq/neq/gt/…) is
268+
// supplied. Hidden for null, undefined, and "" — visible
269+
// only when an action handler has written a real string.
270+
visible: { $state: `/ui/connectionForms/${type}/error` },
267271
},
268272
[`${type}_formConnect`]: {
269273
type: "Button",

0 commit comments

Comments
 (0)