Repository navigation
"flutter pub get" does not terminate when killed #61357
Description
This came up in Dart-Code/Dart-Code#2612. If you run flutter pub get and try to kill it programatically (similar to how Dart-Code would if you clicked the Cancel button on the dialog), the process doesn't terminate.
To repro, you can use this script which creates a pubspec.yaml with an invalid package name, which puts Flutter into an endless loop of retries (which is discussed in dart-lang/pub#2242), and then tries to kill it - however it does not stop.
I repro'd this using latest Flutter master today.
import 'dart:io';
import 'package:path/path.dart' as path;
Future<void> main() async {
// Create a temp project
final projectFolder = Directory(path.join(Directory.systemTemp.path, 'flutter_pub_test'))
..createSync(recursive: true);
// Write a pubspec with a bad package name
File(path.join(projectFolder.path, 'pubspec.yaml'))
..writeAsStringSync('name: sample\n'
"environment:\n sdk: '>=2.10.0 <3.0.0'\n"
'dependencies:\n not_a_real_package:');
// Run "flutter pub get" and print any stdout/stderr output
final proc = await Process.start(
'flutter', ['pub', 'get'],
workingDirectory: projectFolder.path,
);
proc.stdout.listen((s) => print(String.fromCharCodes(s)));
proc.stderr.listen((s) => print(String.fromCharCodes(s)));
// Kill the process and wait for it to end
await Future.delayed(Duration(seconds: 2));
print('Killing process!');
proc.kill();
print('Waiting for exit!');
await proc.exitCode;
}Output:
Running "flutter pub get" in flutter_pub_test...
Because sample depends on not_a_real_package any which doesn't exist (could not find package not_a_real_package at https://pub.dartlang.org), version solving failed.
pub get failed (server unavailable) -- attempting retry 1 in 1 second...
Killing process!
Waiting for exit!
Because sample depends on not_a_real_package any which doesn't exist (could not find package not_a_real_package at https://pub.dartlang.org), version solving failed.
pub get failed (server unavailable) -- attempting retry 2 in 2 seconds...
Because sample depends on not_a_real_package any which doesn't exist (could not find package not_a_real_package at https://pub.dartlang.org), version solving failed.
pub get failed (server unavailable) -- attempting retry 3 in 4 seconds...
Because sample depends on not_a_real_package any which doesn't exist (could not find package not_a_real_package at https://pub.dartlang.org), version solving failed.
pub get failed (server unavailable) -- attempting retry 4 in 8 seconds...
// etc.
This results in orphaned processes being left around forever if the user ever saves pubspec with an invalid package name. I thought it might have been related to dart-lang/sdk#42092, however that seems to have been included in this version of Flutter but it's still not fixed.
(it's very possible this is a similar issue to we have elsewhere, where sending kill signals to a shell-executed process is unreliable.. we get around this in may places by emitting some JSON with the pid and adding that to the list of things to terminate - however pub get doesn't have a machine mode to add that too).
Activity
jason-simmons commentedon Jul 14, 2020
The
proc.kill()call will kill thebin/fluttershell script process but not thedart flutter_tools.snapshot pub getprocess that it spawned.One option would be changing the
bin/flutterscript to trap theSIGTERMsent byproc.killand kill the underlyingdartprocess.DanTup commentedon Jul 14, 2020
We'd probably need to ensure we can do this on Windows with
flutter.battoo?Another option could be to have
--machineflag that just outputs a JSON banner at the top with thepidin it. We already do this in many places (for ex.flutter run --machine) but perhaps this could be more general. (It's possible we could achieve the same with--pid-file, though the pids in startup JSON is fairly consistent across Flutter/package:test/etc. now).DanTup commentedon Aug 4, 2020
Looks like there isn't a
--pid-fileoption we can use here anyway. So as things are, I don't think there's any workaround, so no way an editor can cancel apub getat all. This is quite bad given how easily you can put it in an infinite loop:Some other possible ideas:
stdinto let editors send commands to cancel (perhaps gated on a--machinemode flag)maheshj01 commentedon Jul 29, 2022
Hi @DanTup, I tried running your code and I see the process does get killed. But the output seems to give a misleading message though.
when my pubspec has a constraint
logs
flutter doctor -v (mac)
DanTup commentedon Jul 30, 2022
@maheshmnj I also can't repro on macOS any more. However, I can still repro on Windows. You need to change
'flutter'to'flutter.bat'in theProcess.spawnline (I've also tweaked the code to include anenvironmentfield in thepubspecor it would fail to start fetching the packages).Edit: Confirmed same behaviour on both stable and master.
matanlurey commentedon Jul 9, 2025
It looks like this is fixed at HEAD (we made a bunch of fixes around dangling processes a year ago).
github-actions commentedon Jul 23, 2025
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.