Skip to content

Commit 73c2f82

Browse files
committed
fix: prevent empty mode names from being saved (fixes #5766)
- Add frontend validation in ModesView to prevent empty names from being saved - Add onBlur handler to restore original name if field is left empty - Add backend validation in CustomModesManager.updateCustomMode using modeConfigSchema - Provide user feedback when validation fails - Trim whitespace from mode names before validation This prevents YAML parsing errors caused by empty mode name fields.
1 parent d513b9c commit 73c2f82

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

src/core/config/CustomModesManager.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,18 @@ export class CustomModesManager {
401401

402402
public async updateCustomMode(slug: string, config: ModeConfig): Promise<void> {
403403
try {
404+
// Validate the mode configuration before saving
405+
const validationResult = modeConfigSchema.safeParse(config)
406+
if (!validationResult.success) {
407+
const errorMessages = validationResult.error.errors
408+
.map((err) => `${err.path.join(".")}: ${err.message}`)
409+
.join(", ")
410+
const errorMessage = `Invalid mode configuration: ${errorMessages}`
411+
logger.error("Mode validation failed", { slug, errors: validationResult.error.errors })
412+
vscode.window.showErrorMessage(t("common:customModes.errors.updateFailed", { error: errorMessage }))
413+
return
414+
}
415+
404416
const isProjectMode = config.source === "project"
405417
let targetPath: string
406418

webview-ui/src/components/modes/ModesView.tsx

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -729,11 +729,26 @@ const ModesView = ({ onDone }: ModesViewProps) => {
729729
onChange={(e) => {
730730
const customMode = findModeBySlug(visualMode, customModes)
731731
if (customMode) {
732-
updateCustomMode(visualMode, {
733-
...customMode,
734-
name: e.target.value,
735-
source: customMode.source || "global",
736-
})
732+
const newName = e.target.value.trim()
733+
// Only update if the name is not empty
734+
if (newName.length > 0) {
735+
updateCustomMode(visualMode, {
736+
...customMode,
737+
name: newName,
738+
source: customMode.source || "global",
739+
})
740+
}
741+
}
742+
}}
743+
onBlur={(e) => {
744+
const customMode = findModeBySlug(visualMode, customModes)
745+
if (customMode) {
746+
const newName = e.target.value.trim()
747+
// If the field is empty on blur, restore the original name
748+
if (newName.length === 0) {
749+
// Force re-render by updating the input value
750+
e.target.value = customMode.name
751+
}
737752
}
738753
}}
739754
className="w-full"

0 commit comments

Comments
 (0)