-
Notifications
You must be signed in to change notification settings - Fork 37
Description
Bug Description
runInDedicatedTerminal throws a TypeError when passed a string terminalKey, despite the API signature accepting Uri | string.
Error
TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined
at stat (node:fs:1678:16)
at TerminalManagerImpl.getDedicatedTerminal (dist/extension.js:40773:37)
at async PythonEnvironmentApiImpl.runInDedicatedTerminal (dist/extension.js:37630:26)
Root Cause
In src/features/terminal/terminalManager.ts, the getDedicatedTerminal method accesses .fsPath on terminalKey unconditionally (lines ~343-348):
const uriStat = await fsapi.stat(terminalKey.fsPath); // Crashes when terminalKey is a string
const uriDir = uriStat.isDirectory() ? terminalKey.fsPath : path.dirname(terminalKey.fsPath);
...
const fileName = path.basename(terminalKey.fsPath).replace('.py', '');The internal function signature declares terminalKey: Uri, but the public API signature accepts Uri | string:
// src/api.ts line 1132
runInDedicatedTerminal(
terminalKey: Uri | string,
environment: PythonEnvironment,
options: PythonTerminalExecutionOptions,
): Promise<Terminal>;When a string is passed (e.g., 'my-terminal-key'), the code tries to access .fsPath on a primitive string, which is undefined, causing fs.stat to throw.
Reproduction
const env = environments[0];
const options = { cwd: workspaceUri, args: ['--version'], show: false };
// This crashes:
await api.runInDedicatedTerminal('my-terminal-key', env, options);
// This works:
await api.runInDedicatedTerminal(vscode.Uri.file('/path/to/script.py'), env, options);Suggested Fix
Handle the string case in getDedicatedTerminal:
async getDedicatedTerminal(
terminalKey: Uri | string, // Update type signature
project: Uri | PythonProject,
environment: PythonEnvironment,
createNew: boolean = false,
): Promise<Terminal> {
const part = terminalKey instanceof Uri ? path.normalize(terminalKey.fsPath) : terminalKey;
const key = `${environment.envId.id}:${part}`;
// ... existing cache lookup ...
// Handle string keys differently - use project cwd instead of trying to stat the key
const puri = project instanceof Uri ? project : project.uri;
const config = getConfiguration('python', terminalKey instanceof Uri ? terminalKey : puri);
const projectStat = await fsapi.stat(puri.fsPath);
const projectDir = projectStat.isDirectory() ? puri.fsPath : path.dirname(puri.fsPath);
let cwd: string;
let name: string;
if (terminalKey instanceof Uri) {
const uriStat = await fsapi.stat(terminalKey.fsPath);
const uriDir = uriStat.isDirectory() ? terminalKey.fsPath : path.dirname(terminalKey.fsPath);
cwd = config.get<boolean>('terminal.executeInFileDir', false) ? uriDir : projectDir;
const fileName = path.basename(terminalKey.fsPath).replace('.py', '');
name = `Python: ${fileName}`;
} else {
cwd = projectDir;
name = `Python: ${terminalKey}`;
}
// ... rest of implementation ...
}Environment
- Extension version: 1.19.0
- VS Code version: 1.110.0-insider
- OS: macOS (also reproducible on other platforms)
Additional Context
Discovered during integration testing. The tests runInDedicatedTerminal reuses terminal for same key and runInDedicatedTerminal uses different terminals for different keys fail with this error.