Change:
return taskPromise.then(x => x ?? null); }); <del> return new Promise((c, e) => { const waitForInput = new Promise<void>(resolve => once(e => (e.kind === TaskEventKind.AcquiredInput) && getTaskKey(e.__task) === taskKey, this.taskService.onDidStateChange)(() => { resolve(); })); promise.then(result => { </del> <ins> const result = new Promise<IRunnerTaskSummary | null>((resolve, reject) => { taskDonePromise.then(result => { </ins> taskStarted = true; <del> c(result); }, error => e(error)); </del> <ins> resolve(result); }, error => reject(error)); store.add(token.onCancellationRequested(() => { resolve({ exitCode: undefined, cancelled: true }); this.taskService.terminate(task).catch(() => { }); })); </ins> <del> waitForInput.then(() => { </del> <ins> // Start the timeouts once a terminal has been acquired store.add(didAcquireInput.event(() => { </ins> const waitTime = task.configurationProperties.isBackground ? 5000 : 10000; <del> setTimeout(() => { </del> <ins> // Error shown if there's a background task with no problem matcher that doesn't exit quickly store.add(disposableTimeout(() => { </ins> if (!taskStarted) { <del> const errorMessage = typeof taskId === 'string' ? nls.localize('taskNotTrackedWithTaskId', "The task '{0}' cannot be tracked. Make sure to have a problem matcher defined.", taskId) : nls.localize('taskNotTracked', "The task '{0}' cannot be tracked. Make sure to have a problem matcher defined.", JSON.stringify(taskId)); e({ severity: severity.Error, message: errorMessage }); </del> <ins> const errorMessage = nls.localize('taskNotTracked', "The task '{0}' has not exited and doesn't have a 'problemMatcher' defined. Make sure to define a problem matcher for watch tasks.", typeof taskId === 'string' ? taskId : JSON.stringify(taskId)); reject({ severity: severity.Error, message: errorMessage }); </ins> } <del> }, waitTime); }); </del> <ins> }, waitTime)); // Notification shown on any task taking a while to resolve store.add(disposableTimeout(() => { const message = nls.localize('runningTask', "Waiting for preLaunchTask '{0}'...", task.configurationProperties.name); const buttons = [DEBUG_ANYWAY_LABEL_NO_MEMO, ABORT_LABEL]; const canConfigure = task instanceof CustomTask || task instanceof ConfiguringTask; if (canConfigure) { buttons.splice(1, 0, nls.localize('configureTask', "Configure Task")); } this.progressService.withProgress( { location: ProgressLocation.Notification, title: message, buttons }, () => result.catch(() => { }), (choice) => { if (choice === undefined) { // no-op, keep waiting } else if (choice === 0) { // debug anyway resolve({ exitCode: 0 }); } else { // abort or configure resolve({ exitCode: undefined, cancelled: true }); this.taskService.terminate(task).catch(() => { }); if (canConfigure && choice === 1) { // configure this.taskService.openConfig(task as CustomTask); } } } ); }, 10_000)); })); </ins> }); <ins> return result.finally(() => store.dispose()); </ins> } }

Discussion:
Clone and npm install. Hit F5, it never starts: <img width="484" alt="image" src=""I am on macOS.
This is probably because a prelaunch task is still running / your problem matchers haven't matched anything. Please make sure you have the right problem matchers installed, otherwise I suggest opening issues for them if they don't match correctly.
Would be great if debug could give me a hint.
Will keep open to track it, it's not a rare problem
We should also keep the terminal open if the task fails, currently it closes immediately which can be confusing
Would also be nice if we could cancel the pending launch attempt, e.g. by showing the debug toolbar immediately and disabling all buttons except the stop button. Right now when I get into this state I end up just reloading the whole window and incurring the pain of all extensions reactivating, which takes several seconds on my machine (git, TS etc)
After 10 seconds we'll show !
<!-- UNABLETOLOCATECOMMITMESSAGE repo --Issue marked as unreleased but unable to locate closing commit in repo history. If this was closed in a separate repo you can add the label directly, or comment .
<!-- UNABLETOLOCATECOMMITMESSAGE --Issue marked as unreleased but unable to locate closing commit in issue timeline. You can manually reference a commit by commenting , or directly add the label if you know this has already been releaased