From 1918d9cfe65b483f1fdd0c0a4a1932b4cc4b74c6 Mon Sep 17 00:00:00 2001 From: Roo Code Date: Mon, 12 Jan 2026 11:17:31 +0000 Subject: [PATCH] fix: handle undefined inputValue in ChatTextArea to prevent crash Add defensive null/undefined checks using nullish coalescing operator to handle cases where inputValue is undefined, such as when Gemini model returns blank responses. Fixes #10631 --- .../src/components/chat/ChatTextArea.tsx | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index dd3d0d4c663..099ac7c6379 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -242,7 +242,7 @@ export const ChatTextArea = forwardRef( }, [selectedType, searchQuery]) const handleEnhancePrompt = useCallback(() => { - const trimmedInput = inputValue.trim() + const trimmedInput = (inputValue ?? "").trim() if (trimmedInput) { setIsEnhancingPrompt(true) @@ -256,7 +256,7 @@ export const ChatTextArea = forwardRef( // Memoized check for whether the input has content (text or images) const hasInputContent = useMemo(() => { - return inputValue.trim().length > 0 || selectedImages.length > 0 + return (inputValue ?? "").trim().length > 0 || selectedImages.length > 0 }, [inputValue, selectedImages]) // Compute the key combination text for the send button tooltip based on enterBehavior @@ -506,8 +506,9 @@ export const ChatTextArea = forwardRef( } if (event.key === "Backspace" && !isComposing) { - const charBeforeCursor = inputValue[cursorPosition - 1] - const charAfterCursor = inputValue[cursorPosition + 1] + const safeInputValue = inputValue ?? "" + const charBeforeCursor = safeInputValue[cursorPosition - 1] + const charAfterCursor = safeInputValue[cursorPosition + 1] const charBeforeIsWhitespace = charBeforeCursor === " " || charBeforeCursor === "\n" || charBeforeCursor === "\r\n" @@ -519,7 +520,7 @@ export const ChatTextArea = forwardRef( if ( charBeforeIsWhitespace && // "$" is added to ensure the match occurs at the end of the string. - inputValue.slice(0, cursorPosition - 1).match(new RegExp(mentionRegex.source + "$")) + safeInputValue.slice(0, cursorPosition - 1).match(new RegExp(mentionRegex.source + "$")) ) { const newCursorPosition = cursorPosition - 1 // If mention is followed by another word, then instead @@ -534,9 +535,9 @@ export const ChatTextArea = forwardRef( setCursorPosition(newCursorPosition) setJustDeletedSpaceAfterMention(true) } else if (justDeletedSpaceAfterMention) { - const { newText, newPosition } = removeMention(inputValue, cursorPosition) - - if (newText !== inputValue) { + const { newText, newPosition } = removeMention(safeInputValue, cursorPosition) + + if (newText !== safeInputValue) { event.preventDefault() setInputValue(newText) setIntendedCursorPosition(newPosition) // Store the new cursor position in state @@ -674,8 +675,9 @@ export const ChatTextArea = forwardRef( if (urlRegex.test(pastedText.trim())) { e.preventDefault() const trimmedUrl = pastedText.trim() + const safeInputValue = inputValue ?? "" const newValue = - inputValue.slice(0, cursorPosition) + trimmedUrl + " " + inputValue.slice(cursorPosition) + safeInputValue.slice(0, cursorPosition) + trimmedUrl + " " + safeInputValue.slice(cursorPosition) setInputValue(newValue) const newCursorPosition = cursorPosition + trimmedUrl.length + 1 setCursorPosition(newCursorPosition) @@ -820,7 +822,8 @@ export const ChatTextArea = forwardRef( if (lines.length > 0) { // Process each line as a separate file path - let newValue = inputValue.slice(0, cursorPosition) + const safeInputValue = inputValue ?? "" + let newValue = safeInputValue.slice(0, cursorPosition) let totalLength = 0 // Using a standard for loop instead of forEach for potential performance gains. @@ -839,7 +842,7 @@ export const ChatTextArea = forwardRef( } // Add space after the last mention and append the rest of the input - newValue += " " + inputValue.slice(cursorPosition) + newValue += " " + safeInputValue.slice(cursorPosition) totalLength += 1 setInputValue(newValue)