fix: prevent Ctrl+V crash when clipboard contains non-text data#1758
fix: prevent Ctrl+V crash when clipboard contains non-text data#1758exqqstar wants to merge 2 commits intoMoonshotAI:mainfrom
Conversation
Two-layer fix for TypeError crash on paste: 1. _SafePyperclipClipboard: wraps PyperclipClipboard.get_data() to treat None/non-string payloads as empty text, protecting all clipboard access paths in prompt_toolkit (not just our Ctrl+V handler). Covers MoonshotAI#1750. 2. _try_paste_media() return value: when images are detected but the model does not support image_in, the paste event is now consumed (return True) instead of falling through to the text paste path.
There was a problem hiding this comment.
Pull request overview
Prevents a TypeError crash when pasting from the clipboard (Ctrl+V and other prompt_toolkit paste paths) if the clipboard contains non-text data (e.g., screenshots), and ensures unsupported image paste events are consumed instead of falling through to text paste.
Changes:
- Introduces
_SafePyperclipClipboardto treatNone/non-string clipboard payloads as empty text. - Updates
_try_paste_media()to consume paste events when images are detected but the current model lacksimage_in. - Adds/updates tests covering the unsupported-image consumption behavior and
Noneclipboard payload handling.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/kimi_cli/ui/shell/prompt.py |
Adds safe clipboard wrapper and adjusts media paste return semantics to avoid Ctrl+V crash/fallthrough. |
tests/ui_and_conv/test_prompt_clipboard.py |
Updates image-unsupported test expectations and adds a regression test for pyperclip.paste() -> None. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if parts: | ||
| event.current_buffer.insert_text(" ".join(parts)) | ||
| event.app.invalidate() | ||
| return bool(parts) | ||
| return bool(parts) or unsupported_images | ||
|
|
There was a problem hiding this comment.
_try_paste_media() now returns True even when no content is inserted (when images are detected but unsupported), but its docstring still says it returns True only if media content was inserted. Please update the docstring to reflect the new "paste was handled/consumed" semantics so callers/tests don’t rely on the old meaning.
src/kimi_cli/ui/shell/prompt.py
Outdated
| data = super().get_data() | ||
| except TypeError as exc: | ||
| logger.debug( | ||
| "Ignoring non-text clipboard payload in text paste handler: {error}", |
There was a problem hiding this comment.
The debug message in _SafePyperclipClipboard.get_data() says "in text paste handler", but this clipboard wrapper is used for all prompt_toolkit paste operations (Ctrl+V, Ctrl+Y, Vi p, etc.). Consider rewording the log message to be accurate (e.g., "clipboard get_data" / "paste") to avoid confusion when debugging.
| "Ignoring non-text clipboard payload in text paste handler: {error}", | |
| "Ignoring non-text clipboard payload in clipboard get_data: {error}", |
| @@ -199,9 +200,11 @@ def test_paste_image_unsupported_model(monkeypatch, capsys) -> None: | |||
|
|
|||
| result = ps._try_paste_media(cast(KeyPressEvent, event)) | |||
|
|
|||
| # No image placeholder inserted, returns False so caller can fall back to text paste | |||
| assert result is False | |||
| # Media was recognized, so the paste event should be consumed even though the | |||
| # model cannot accept image input. | |||
| assert result is True | |||
There was a problem hiding this comment.
capsys is accepted by test_paste_image_unsupported_model_consumes_paste but not used. Either drop the fixture parameter or use it to assert the expected warning text is printed (this PR description calls out that the warning is still shown).
- Update _try_paste_media() docstring to reflect "paste handled" semantics - Fix misleading debug log message in _SafePyperclipClipboard - Remove unused capsys fixture from test
Related Issue
Resolve #1757
Related to #1750
Description
Two-layer fix for
TypeErrorcrash when pressing Ctrl+V with non-text clipboard content (e.g. a screenshot on a modelthat doesn't support image input, or any payload where
pyperclip.paste()returnsNone).Layer 1:
_SafePyperclipClipboardWraps
PyperclipClipboard.get_data()to catchTypeErrorand treatNone/non-string payloads as empty text(
ClipboardData()). This protects all clipboard access paths in prompt_toolkit — not just our explicit Ctrl+Vhandler, but also built-in paste operations (Ctrl+Y, Vi
p, etc.).Layer 2:
_try_paste_media()return valueWhen images are detected in the clipboard but the current model does not support
image_in, the paste event is nowconsumed (
return True) instead of returningFalseand falling through to the text paste path. The "Image input isnot supported" warning is still printed.
What's NOT changed
kimi-k2.5) — behavior unchanged._try_paste_media()still returnsFalsewhen image caching fails — existing fallback semantics preserved.Checklist
make gen-changelogto update the changelog.make gen-docsto update the user documentation.