{"record":{"id":"19671ad0f940f477","repo":"DayuanJiang/next-ai-draw-io","slug":"invalid-preset-name","errorCode":null,"errorMessage":"Invalid preset name","messagePattern":"Invalid preset name","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"electron/main/ipc-handlers.ts","lineNumber":160,"sourceCode":"    ipcMain.handle(\"config-presets:get-current\", () => {\n        return getCurrentPreset()\n    })\n\n    ipcMain.handle(\"config-presets:get-current-id\", () => {\n        return getCurrentPresetId()\n    })\n\n    ipcMain.handle(\n        \"config-presets:save\",\n        (\n            _event,\n            preset: Omit<ConfigPreset, \"id\" | \"createdAt\" | \"updatedAt\"> & {\n                id?: string\n            },\n        ) => {\n            // Validate preset name\n            if (typeof preset.name !== \"string\" || !preset.name.trim()) {\n                throw new Error(\"Invalid preset name\")\n            }\n\n            // Sanitize config to only allow whitelisted keys\n            const sanitizedConfig = sanitizePresetConfig(preset.config ?? {})\n\n            if (preset.id) {\n                // Update existing preset\n                return updatePreset(preset.id, {\n                    name: preset.name.trim(),\n                    config: sanitizedConfig,\n                })\n            }\n            // Create new preset\n            return createPreset({\n                name: preset.name.trim(),\n                config: sanitizedConfig,\n            })\n        },","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/DayuanJiang/next-ai-draw-io/blob/155ef4f7acd29c9d46fb6fc35c92e6e6955a6ce1/electron/main/ipc-handlers.ts#L142-L178","documentation":"The IPC handler config:save-preset requires preset.name to be a non-empty trimmed string before sanitizing and persisting the config.","triggerScenarios":"Renderer sends config:save-preset with preset.name = '', whitespace-only, undefined, or a non-string value (e.g. number).","commonSituations":"Form state where the name input was never filled, or a refactor that renamed the field (label vs name).","solutions":["Ensure the save form validates name before calling the IPC","Pass preset.name as a non-empty trimmed string","Add a required-field check in the UI so users can't submit blank names"],"exampleFix":"// before\nawait ipcRenderer.invoke('config:save-preset', { name: '', config })\n\n// after\nconst name = nameInput.trim()\nif (!name) throw new Error('Preset name is required')\nawait ipcRenderer.invoke('config:save-preset', { name, config })","handlingStrategy":"validation","validationCode":"const isValidPreset = (p: { name?: unknown }) =>\n  typeof p?.name === 'string' && p.name.trim().length > 0","typeGuard":"const hasValidPresetName = (p: unknown): p is { name: string } =>\n  typeof (p as any)?.name === 'string' && (p as any).name.trim() !== ''","tryCatchPattern":"try { await ipcRenderer.invoke('config:save-preset', preset) } catch (e) { showFieldError('name', (e as Error).message) }","preventionTips":["Require the name input in the preset form before enabling save","Trim and validate preset shape in the renderer before IPC","Test the IPC boundary with empty-name payloads"],"tags":["ipc","electron","validation","preset"],"backgroundTag":"required-field-missing","analyzedSha":"155ef4f7acd29c9d46fb6fc35c92e6e6955a6ce1","analyzedAt":"2026-08-27T11:40:38.297Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}