[BUG] [VS Code] "New session" ignores the requesting panel's editor group and opens a new locked group unless some group holds only Claude tabs
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Clicking New session (the + in a Claude editor panel, or the New session button in the "Session manager" section of the Claude Code sidebar) no longer opens the new session as a tab in the editor group I am working in. Instead it creates a new editor group at the far right and locks it. Opening an existing, currently closed session from the sessions list behaves the same way; it goes through the same request.
The trigger is the absence of any editor group that contains only Claude tabs. Working on a Markdown file side by side with Claude in one group, which is the normal way to iterate on a document, is enough to remove the only candidate. If I then drag the new session tab back into my working group, the empty locked group stays behind (VS Code does not auto-close locked groups), it no longer qualifies either because it has no tabs, and the next New session creates a third group.
What Should Happen?
The new session opens as a tab in the group that issued the request, or in the active editor group when there is no issuing panel, the same way any other editor opens.
Error Messages/Logs
Steps to Reproduce
- Set
claudeCode.preferredLocationtopanel. - Open one Claude session as an editor tab. Open any file (for example a
.md) as a second tab in the same editor group. Make sure no other editor group in the window contains only Claude tabs; the check below scans all groups, so a single Claude-only group anywhere suppresses the bug. - Click New session (either entry point above). Step 1 only matters for the panel
+; the sessions-list button behaves the same under either setting.
Claude Model
Not sure / Multiple models
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
Claude Code v2.1.247
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
WSL (Windows Subsystem for Linux)
Additional Information
Actual Behavior
A new editor group is created (VS Code default: to the right), the session opens there, and the group is locked.
Root cause (from the shipped extension.js, 2.1.263)
De-minified for readability; names are mine. Behavior is faithful to the shipped code; an already-open-session early return and a dead ViewColumn.Beside initializer are elided.
// "Is this a Claude group?" = every tab in the group is a Claude webview
function isPureClaudeGroup(group) {
return group.tabs.length > 0 &&
group.tabs.every(t => t.input instanceof vscode.TabInputWebview &&
t.input.viewType.includes("claudeVSCodePanel"));
}
function findClaudeGroup() {
const { activeTabGroup, all } = vscode.window.tabGroups;
return isPureClaudeGroup(activeTabGroup) ? activeTabGroup : all.find(isPureClaudeGroup);
}
// helper that already exists and is already used by "claude-vscode.primaryEditor.open"
// and by reopen-closed-session:
function claudeGroupOrActive() {
return findClaudeGroup()?.viewColumn ?? vscode.ViewColumn.Active;
}
// in createPanel(sessionId, prompt, viewColumn, groupId, isFullEditor):
let startedInNewColumn = false, column;
if (viewColumn !== undefined) {
column = viewColumn;
} else {
const g = findClaudeGroup();
if (g) column = g.viewColumn;
else { column = this.findUnusedColumn(); startedInNewColumn = true; } // first unused 1..9, else Beside => new group
}
vscode.window.createWebviewPanel("claudeVSCodePanel", "Claude Code", column, ...);
// caller ("claude-vscode.editor.open"):
if (startedInNewColumn) await vscode.commands.executeCommand("workbench.action.lockEditorGroup");
Two webview requests reach claude-vscode.editor.open without a viewColumn: new_conversation_tab (the panel +) passes only (sessionId, initialPrompt), and open_in_editor (the sidebar sessions list) passes (sessionId, undefined, undefined, newSessionGroupId, true). In both cases viewColumn is undefined, so the heuristic always runs. Note that the sessions-list button ignores claudeCode.preferredLocation entirely: its openInEditor() call is unconditional, so setting sidebar does not change this path. isPureClaudeGroup conflates "the group the user dedicated to Claude" with "a group that happens to contain nothing else." As soon as a single file tab shares the only Claude group, no group qualifies and the fallback creates and locks a new one.
For the panel +, the extension already knows which panel issued the request: the same class reads this.panelTab?.viewColumn to place the plan preview one column to its right. That information is not passed along on the New session path.
Proposed fix
Two small changes:
- In the
new_conversation_tabhandler, passthis.panelTab?.viewColumn ?? claudeGroupOrActive()as the third argument toclaude-vscode.editor.open, socreatePaneltakes the explicit-column branch. Note the behavior change this implies: when a pure Claude group exists elsewhere, the new tab follows the requesting panel instead of jumping to that group, which is what the+on a panel suggests. - For entry points with no originating panel (
open_in_editorfrom the sessions list,claude-vscode.editor.openLast, the command palette), passclaudeGroupOrActive()instead of falling through tofindUnusedColumn(). That helper is already in the file and already used for the primary-editor command and for reopening a closed session, so this reuses an existing fallback rather than adding one.
I assume the dedicated locked group is intentional: VS Code routes new editors away from locked groups, so it keeps diffs and file links that Claude opens from landing on top of the chat. If that first-open behavior should stay, the narrower fix is to keep findUnusedColumn() plus the lock only when no Claude tab exists anywhere in the window, and use claudeGroupOrActive() when Claude tabs exist but none sits in a pure group. Either variant preserves the dedicated group for users who keep one and stops penalizing users who do not.
Workaround (verified on 2.1.263)
A keybinding that calls the internal command with an explicit column, using runCommands to pass positional arguments. Empty strings behave like undefined for session id and prompt; -1 is ViewColumn.Active.
{
"key": "ctrl+alt+n",
"command": "runCommands",
"args": {
"commands": [
{ "command": "claude-vscode.editor.open", "args": ["", "", -1] }
]
}
}
Side effect: the handler rewrites claudeCode.preferredLocation to panel on every call, a no-op if that is already your setting. If you keep sidebar as your default, pass ["", "", -1, "", true] instead; the fifth argument is the isFullEditor flag, which also gates that rewrite. It renders the tab in full-editor mode, which hides the panel header (title, session history, and the + button), the same mode the sidebar's session list uses when it opens a session in the editor.
This relies on an unversioned internal signature, so it is not a substitute for a fix.
Related
- #36461 ("New Claude Code tab ignores active editor group/column") was closed as not planned. It described the symptom; this report adds the code path and the fact that the "pure Claude group" test is what makes the fallback fire for anyone who keeps a file open next to a session.
- Changelog 2.1.257 mentions fixing Cmd/Ctrl+Shift+T and deep-link opens "placing the Claude tab outside the Claude editor group." The behavior above appeared for me around that version range; I cannot say whether that change introduced it.
3 Comments
+1, reproduced on v2.1.267. Every "+ New session" click opens a brand-new locked editor group even when a group with only Claude tabs already exists nearby, splitting the layout further each time. Setting
claudeCode.preferredLocationto"sidebar"does not prevent it for this button specifically — see my repro notes on #80148.+1, also on v2.1.267. It also always creates a locked group, ignoring VS Code's auto lock groups settings.
reproduced on 2.1.268 It is very annoying