Repository navigation
Flutter: Change SDK does not detect multiple SDKs #4607
Description
Describe the bug
When there are multiple Flutter SDKs installed, the VSCode extension does not correctly identify them:
In my particular case, I have two installations:
~Development/github.com/flutter/flutter/bin/flutter~Development/github.com/shorebirdtech/_shorebird/shorebird/bin/shorebird/cache/flutter/bin/flutter
The VSCode extension only detects the latter even though my PATH contains the former:
Run from within VSCode's integrated terminal:
echo $PATH
/Users/felix/Desktop/sage/bin:/opt/homebrew/opt/openssl@3/bin:/Users/felix/Downloads/google-cloud-sdk/bin:/Users/felix/.nvm/versions/node/v18.15.0/bin:/Applications/Postgres.app/Contents/Versions/14/bin:/Users/felix/Library/Android/sdk/platform-tools:/Users/felix/Library/Android/sdk/tools:/Users/felix/Development/github.com/chromium/depot_tools:/opt/homebrew/opt/openjdk/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Users/felix/Desktop/sage/bin:/opt/homebrew/opt/openssl@3/bin:/Users/felix/Downloads/google-cloud-sdk/bin:/Users/felix/.nvm/versions/node/v18.15.0/bin:/Applications/Postgres.app/Contents/Versions/14/bin:/Users/felix/Library/Android/sdk/platform-tools:/Users/felix/Library/Android/sdk/tools:/Users/felix/Development/github.com/chromium/depot_tools:/opt/homebrew/opt/openjdk/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/Users/felix/.cargo/bin:/Users/felix/Development/github.com/flutter/flutter/bin:/Users/felix/fvm/default/bin/cache/dart-sdk/bin:/Users/felix/.pub-cache/bin:/Users/felix/Development/github.com/shorebirdtech/_shorebird/shorebird/bin:/Users/felix/Development/github.com/flutter/flutter/bin:/Users/felix/fvm/default/bin/cache/dart-sdk/bin:/Users/felix/.pub-cache/bin:/Users/felix/Development/github.com/shorebirdtech/_shorebird/shorebird/bin
Run from Mac terminal:
/Users/felix/.shorebird/bin:/Users/felix/Desktop/sage/bin:/opt/homebrew/opt/openssl@3/bin:/Users/felix/Downloads/google-cloud-sdk/bin:/Users/felix/.nvm/versions/node/v18.15.0/bin:/Applications/Postgres.app/Contents/Versions/14/bin:/Users/felix/Library/Android/sdk/platform-tools:/Users/felix/Library/Android/sdk/tools:/Users/felix/Development/github.com/chromium/depot_tools:/opt/homebrew/opt/openjdk/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Users/felix/.cargo/bin:/Users/felix/Development/github.com/flutter/flutter/bin:/Users/felix/fvm/default/bin/cache/dart-sdk/bin:/Users/felix/.pub-cache/bin:/Users/felix/Development/github.com/shorebirdtech/_shorebird/shorebird/bin
I have disabled the setting to update the PATH:
When I override the SDK path in my user settings.json it still does not appear to have any effect:
The only way I'm able to work around this is to move the original installation to a different path, relaunch vscode, and revert the rename.
To Reproduce
Steps to reproduce the behavior:
- Install multiple Flutter SDKs in different locations
- Open the VSCode command palette and run the Flutter: Change SDK command
- Note that only one of the two installation paths is detected and there is no way to change it.
Expected behavior
I expect to be able to configure the SDK paths
Please complete the following information:
- Operating System and version: MacOS v13.0
- VS Code version:
Version: 1.79.1 (Universal)
Commit: 4cb974a7aed77a74c7813bdccd99ee0d04901215
Date: 2023-06-12T16:16:49.215Z (1 wk ago)
Electron: 22.5.7
Chromium: 108.0.5359.215
Node.js: 16.17.1
V8: 10.8.168.25-electron.0
OS: Darwin arm64 22.1.0
- Dart extension version:
v3.66.0 - Dart/Flutter SDK version: Flutter 3.10.5 and Dart 3.0.5



Activity
bryanoltman commentedon Jun 22, 2023
Fellow Shorebirder here, and I'm seeing this as well. The
flutterresolved by my path is/Users/bryanoltman/Documents/flutter/bin/flutter, but vscode only seems to pick up a different location (also in_shorebird/shorebird/bin/cache/flutter).bryanoltman commentedon Jun 22, 2023
I've disabled
Add sdk to terminal path, so the terminal in VS Code finds the correct Flutter/Dart, but theRun/Debugoptions still point to the shorebird flutterfelangel commentedon Jun 22, 2023
After troubleshooting it appears the "dart.flutterSdkPath" expects path to the Flutter directory not
bin/flutter. Thanks @DanTup 🙏felangel commentedon Jun 22, 2023
Closing in favor of #4608
DanTup commentedon Jun 22, 2023
@bryanoltman are your issues resolved by the info above too, or are you still seeing anything unexpected/incorrect?
bryanoltman commentedon Jun 22, 2023
I'm not sure what the correct behavior is, but after explicitly setting my Flutter SDK path to
/Users/bryanoltman/Documents/flutter/bin/flutterindart.flutterSdkPaths, that is the only one I see in VS Code'sFlutter: Change SDKmenu. I'm not sure how the auto-detect logic works, but the issue seems to be resolved for now!DanTup commentedon Jun 22, 2023
You shouldn't have
bin/flutteron the end, these are paths to the SDKs, not to the binaries.If that's the only SDK in the
dart.flutterSdkPathssetting, then it's expected that's the only one that shows up here. The Change SDK commands only ever looks atdart.flutterSdkPaths. It searches the locations you've listed here for SDKs, and then shows a picklist of them. If any of them happen to match the current SDK being used, it will mark them as such - but it won't list anything not in this setting.That setting is only really useful if you have multiple SDKs you want to switch between. Otherwise, you just want to set the singular
dart.flutterSdkPathsetting.bryanoltman commentedon Jun 22, 2023
Ack, sorry, I did not have
/bin/flutteron the end – that was a copy/paste error on my side :)DanTup commentedon Jun 23, 2023
So is everything working as expected now, or does something still seem wrong / confusing?
felangel commentedon Jun 23, 2023
The confusing bit for me is it wasn’t clear what dart.flutterSdkPath is supposed to point to and when pointing to flutter/bin/flutter I received no error/warning so from my perspective it appeared as though this setting wasn’t working. It’s also confusing/unclear how flutter is auto-detected when there are multiple installations present. I would expect to be able to see all flutter installations when I use the change flutter sdk command and be able to switch between them but instead it sounds like the extension picks an arbitrary one and I need to manually specify those in settings as dart.flutterSdkPaths. This is especially confusing because even when dart.flutterSdkPaths is empty, the change flutter sdk list is not empty so it’s not immediately obvious what the dart.flutterSdkPaths does either.
DanTup commentedon Jun 26, 2023
Got it - will fix that in #4608.
I'm not sure what you mean by "all Flutter installations". The "Change SDK" option will show you all SDKs it finds from the
sdkPathssetting plus whatever the current in-use SDK is. That setting exists specifically to control what SDKs are offered here, and the current SDK is added to it (if it's not already in that set) to make it easier to see the path.Do you mean for the current session? The one used by the current session never comes from
sdkPaths, only fromsdkPath. When the extension loads, it tries to find an SDK by looking in a number of places (including thesdkPathsetting,PATH, a few well-known folders, and by looking in.dart_tool/package_config.json) that are defined in order of priority.The "Change SDK" setting never picks anything arbitrarily, it shows the list from the
sdkPathssetting plus whatever the SDK in-use is (if it's not already in that set). When you choose something from this, it's written into thesdkPathsetting for the current workspace. Selecting "Auto Detect" will unsetsdkPathfor the current workspace, so the normal search will occur.This list should only include the active SDK if you don't have anything in
dart.flutterSdkPaths*. If that's not what you see, it sounds like a bug.* I just noticed that the Dart Change SDK command is currently available in a Flutter workspace which is quite confusing (because it'll show some Dart SDKs that aren't Flutter, and selecting one won't actually change anything). I've pushed a fix for that in 7a16a8c.
yahu1031 commentedon Aug 3, 2023
Faced a similar issue. These logs may help - https://cdn.sourceb.in/bins/iq7NdMEOlt/0
DanTup commentedon Aug 7, 2023
@yahu1031 can you confirm what the issue is you're seeing? If you're not getting the right SDK and not seeing a warning about an invalid path, please file a new issue with the log and a clear description of the problem (such as which SDK you're expecting to be found, which is being used, and what values you have for the relevant SDK settings). Thanks!
1 remaining item
DanTup commentedon Aug 7, 2023
We don't look in (many) arbitrary folders in the homedir - are you sure it's not selecting this one because it's on
PATH, or because it's referenced in.dart_tool/package_config.json?If you think it's making the wrong (or at least sub-optimal) decision and can provide an explanation of why it should select a different one, do file an issue and we can try to tweak the rules. Ideally we'd select the best SDK in all cases and you'd never need to use the setting unless you want to specifically override for that project - in practice it's tricky to get to that though :-)
eseidel commentedon Feb 17, 2024
We continue to get customers hitting this issue, since
shorebird releasewill end up using a flutter buried deep in our cache directory, which sometimes ends up leaving around a path to that flutter in .dart_tool (we try to avoid it happening), which VSC then finds and uses that flutter on your path, thus breakingflutterfor the customer from within VSC. I guess we could write ashorebird repaircommand which found your system flutter and ranflutter pub getin your project directory and then asked you to restart your VSC terminal?I wonder how
fvmdeals with this.DanTup commentedon Feb 17, 2024
I'm not very familiar with fvm, but I think it's probably simpler for it, because once an SDK is selected, it'll be used for everything - I don't think you could accidentally end up with a different path written (besides when explicitly changing).
I don't think this is entirely a VS Code problem - the analyzer will also use
.dart_tool/package_config.jsonto resolve packages - so if it's pointing to "the wrong one", the user could (in theory) see analysis issues different to what they'd see during compilation. I think the real problem here is that the package_config is "wrong".(but to be clear, you can override the Flutter SDK location with the
config.flutterSdkPath. The one in package_config takes precedence over the one onPATHbut not over a user-setting)Out of interest - why didn't shorebirdtech/shorebird#1193 resolve this? Having the package_config put back at the end of shorebird commands seems like the best solution to me, because all tools using package_config will resolve Flutter to the right place.
I don't think changing the search order is a good fix (because I think it will lead to other problems), but if we were to do something in VS Code, I think some possible options would be:
.vscodeignorefile inside the Shorebird Flutter SDK, and update VS Code to ignore any SDKs with this file (this would be implemented in the existing "is this folder a Flutter SDK?" check, and cause the search to just continue with the next location)dart.flutterSdkPath(we could do this globally, or just in the current project). Having that setting would solve the issue because we'd always take this path in preference to PATH or package_configI think (1) would be better (because I think the UI for 2 would be messy with VS Code's limited options, and not bothering the user is better than asking them to make choices they might not entirely understand).
Both of them still have the problem that there's a potential for different compile errors to what the user sees in the IDE (if the Shorebird version doesn't match the one we end up using), but I presume that's something you're happy to be responsible for (because I don't think there's any way VS Code could help with it).
Thoughts?
eseidel commentedon Feb 17, 2024
I think shorebirdtech/shorebird#1193 did mostly resolve this. But it's a racey solution. Users seem to still sometimes hit this (maybe control-C isn't caught by the finally https://github.com/shorebirdtech/shorebird/pull/1231/files#diff-646679cb573f83b50cd0f4f92cfbe160f2085dd3a00436d82114c68989aad462R260 ) and once they do, they're stuck. I suspect we could change our flutter fork to detect that it's being run directly and show a clear error.
I'm comfortable with not doing anything yet. This isn't nearly as large a problem as it was before we added the "system flutter pub get. We can continue to monitor how frequently people hit this. I do like the .vscodeignore idea, since this is almost entirely a terminal path problem AFAICT. The analysis errors, etc quickly would get fixed any time they ran the "correct" flutter for anything. (Including possibly hitting the build button in VSC?)
A opt-out-file solution also would give Shorebird (and other tools) ways to opt-out of this detection. I expect we will eventually expose our
flutter(anddart) installs directly once they're built to be generally usable, at which point we could just remove the file and users and VSC wouldn't have to change anything.DanTup commentedon Feb 17, 2024
You could try something like
ProcessSignal.sigint.watch().listen()(and maybe alsosigterm?) to ensure you clean up on those signals (not sure they work on Windows though, it might be worth also keeping the finally and just ensuring only one of them does the work).Yep, I would expect so. In the past I think Flutter used to write a warning "Hey, the version of Flutter you're using doesn't match what's in package_config" but I haven't seen that in a while, so not sure if it's just silent about it now (and overwrites).
Having an opt-out file is a trivial change and is not shorebird-specific, so if you wan to try it out I'm happy to add something for this. We could name it something more generic (
.sdkignore) so if other tools do something similar to VS Code when trying to locate SDKs, they could do similar.Ofcourse, it'd be nice if shorebird could function without the file being updated at all - but I don't know if that's feasible because I'm not familiar with exactly what's happening inside it/Flutter.
eseidel commentedon Feb 17, 2024
Yeah, we'd love to be able to run our version of
flutterw/o affecting the user's cache files in any way. I've not looked into seeing if that's possible. It feels like the kind of pathway that could quickly rot.The reason why we need to do this at all is to support patching. When you patch an older app, we need to use the exact version of Flutter that app was built with (because Dart snapshots aren't intended to be stable between versions). In order to do that, we might have to switch your flutter, just for that one build of your app (but don't want to affect your system flutter).
Additionally we also currently use our flutter because it's slightly modified (to pull our modified engine) and we want to not pollute your Flutter's artifact caches, etc. But that's also technically solvable over time if we modified upstream Flutter to support using a separate temporary cache for artifacts or similar.
DanTup commentedon Feb 17, 2024
Gotcha. Well in the short-term I'd certainly look at capturing sigint/sigterm to run your finally code, and if you want to add an ignore file we can use to skip over the SDK, that's an easy change that shouldn't impact anything else - just open a new issue for it if you want me to do that.
markymakes-dev commentedon Apr 8, 2024
Is this issue solved? I just encounter this one.
DanTup commentedon Apr 8, 2024
@vault-me it's hard to answer without more details about the behaviour you're seeing. No changes were made as a result of this issue (except for #4608) for the reasons discussed above.
The current behaviour is definitely inconvenient for Shorebird, but we don't currently have a good way around this that doesn't just move the problem elsewhere (eg. analyzer using a different version to the rest of the Dart extension).
My understanding is that Shorebird tries to restore the
package_configto avoid this issue, but I don't know how reliable that has been in practice (though I also don't know if that would solve the problem you're experiencing without more info).manav828 commentedon Dec 10, 2024
1733845159562_shorebird.log

why my preview not build
DanTup commentedon Dec 10, 2024
@manav828 this repository is for the Dart/Flutter VS Code extensions, I think your question is best asked in the Shorebird repo (or Discord server, or similar). Thanks!
DanTup commentedon Jul 2, 2026
FYI, in #6109 I'm demoting
.dart_tool/package_config.jsonto belowPATHin the SDK search order. If the SDK we select (eg. fromPATH) is not the same as the one in.dart_tool/package_config.json(which would result in differences between the version ofpackage:flutterthat the analysis server is using and the one we will triggerfluttercommands in), you'll see the usual popup that tells you packages are missing or out-of-date and encouraging you to re-runpub get.