Skip to content

Tab key inserts a literal tab into BaseTextInput #3268

@shenyankm

Description

@shenyankm

What happened?

Pressing Tab in a Qwen Code input backed by BaseTextInput / useTextBuffer can fall through to the default buffer handler and insert a literal \t character into the input buffer.

This is unexpected because Tab is used as a control key for behaviors such as completion, focus switching, or other consumer-specific handling. If the active consumer does not intercept Tab via onKeypress, the buffer content is changed by the default insertion path.

Reproduction:

  1. Start Qwen Code in interactive mode.
  2. Focus an input/composer that uses BaseTextInput.
  3. Press Tab when no completion or other Tab handler consumes the key.
  4. Observe that a literal tab/extra indentation is inserted into the input.
    Before fix:
    Image
    After local fix:

Image

What did you expect to happen?

Pressing Tab as a keypress should not insert a literal \t into the text buffer.

The default input handler should ignore Tab unless pasted content is being handled. Consumers that need Tab behavior should intercept it via onKeypress, for example for completion or focus-related behavior.

Client information

Client Information

Platform: Windows (win32 x64, OS version 10.0.26200)

Qwen Code: 0.14.4 (40670d72c)
Runtime: Node.js v24.14.1 / npm 11.12.1
OS: win32 x64 (10.0.26200)

Auth: 阿里云百炼 Coding Plan
Base URL: https://coding.dashscope.aliyuncs.com/v1
Model: qwen3.5-plus
Fast model: N/A
Session ID: 256d647c-b4a2-4f63-bcb6-6107cdbeb81c
Sandbox: no sandbox
Proxy: no proxy
Memory usage: 253.3 MB


### Login information

Using 阿里云百炼 Coding Plan with DashScope-compatible base URL:
`https://coding.dashscope.aliyuncs.com/v1`

No proxy configured.


### Anything else we need to know?

Local analysis: a local fix commit (`883dbf8cc68cbe100154c7cd19231d7e41eff2f6`) prevents literal Tab insertion in `BaseTextInput` and `useTextBuffer`.

The change is focused on:
- `packages/cli/src/ui/components/BaseTextInput.tsx`
- `packages/cli/src/ui/components/shared/text-buffer.ts`

A before/after demo should show that pressing Tab no longer changes the prompt buffer, while pasted text remains handled by the paste path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions