fix: sanitize component key input in pipeline editor#8
Conversation
Automatically convert spaces to underscores and strip invalid characters as users type component keys. Adds helper text showing the allowed format. Prevents cryptic server-side validation errors from Vector's identifier requirements.
Greptile SummaryThis PR adds input sanitization to the component key field in the pipeline detail panel, converting spaces to underscores, stripping invalid characters, and prefixing leading digits — preventing cryptic Zod validation errors at save time. It introduces a local Key issues found:
The sanitization logic ( Confidence Score: 3/5
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["User types in Component Key input"] --> B["handleKeyChange(raw)"]
B --> C["sanitized = raw\n.replace spaces→_\n.replace invalid chars\n.prefix leading digit"]
C --> D{sanitized\nnon-empty?}
D -- "No (e.g. '!!!')" --> E["setDisplayKey(storeKey)\n(revert to last saved key)"]
D -- "Yes" --> F["setDisplayKey(raw) ⚠️\n(should be sanitized)"]
F --> G["updateNodeKey(id, sanitized)\n→ Zustand store"]
G --> H["storeKey changes\n→ useEffect fires"]
H --> I["setDisplayKey(storeKey)\n(snaps to sanitized — causes flicker)"]
I --> J["Input shows sanitized value"]
E --> J
|
| if (selectedNodeId) { | ||
| updateNodeKey(selectedNodeId, key); | ||
| const sanitized = raw | ||
| .replace(/\s+/g, "_") | ||
| .replace(/[^a-zA-Z0-9_]/g, "") | ||
| .replace(/^(\d+)/, "_$1"); | ||
| updateNodeKey(selectedNodeId, sanitized); | ||
| } |
There was a problem hiding this comment.
Empty string written to store when all characters are stripped
If the user types a value composed entirely of characters that are removed by the second replace step (e.g. "!!!"), sanitized becomes "" and updateNodeKey(selectedNodeId, "") is called. This stores an empty component key, which will silently fail Zod validation only at save time, potentially leaving the user with a broken node state.
Adding a guard prevents this silent bad state:
| if (selectedNodeId) { | |
| updateNodeKey(selectedNodeId, key); | |
| const sanitized = raw | |
| .replace(/\s+/g, "_") | |
| .replace(/[^a-zA-Z0-9_]/g, "") | |
| .replace(/^(\d+)/, "_$1"); | |
| updateNodeKey(selectedNodeId, sanitized); | |
| } | |
| const sanitized = raw | |
| .replace(/\s+/g, "_") | |
| .replace(/[^a-zA-Z0-9_]/g, "") | |
| .replace(/^(\d+)/, "_$1"); | |
| if (sanitized) updateNodeKey(selectedNodeId, sanitized); |
Summary
Test plan