Skip to content

Flutter: Change SDK does not detect multiple SDKs #4607

Closed

Description

@felangel

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

Screenshot 2023-06-22 at 2 19 50 PM

I have disabled the setting to update the PATH:

Screenshot 2023-06-22 at 2 23 59 PM

When I override the SDK path in my user settings.json it still does not appear to have any effect:

Screenshot 2023-06-22 at 2 25 45 PM

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:

  1. Install multiple Flutter SDKs in different locations
  2. Open the VSCode command palette and run the Flutter: Change SDK command
  3. 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

  1. bryanoltman commented on Jun 22, 2023

    @bryanoltman

    Fellow Shorebirder here, and I'm seeing this as well. The flutter resolved 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).

  2. bryanoltman commented on Jun 22, 2023

    @bryanoltman

    I've disabled Add sdk to terminal path, so the terminal in VS Code finds the correct Flutter/Dart, but the Run/Debug options still point to the shorebird flutter

  3. felangel commented on Jun 22, 2023

    @felangel
    ContributorAuthor

    After troubleshooting it appears the "dart.flutterSdkPath" expects path to the Flutter directory not bin/flutter. Thanks @DanTup 🙏

  4. felangel commented on Jun 22, 2023

    @felangel
    ContributorAuthor

    Closing in favor of #4608

  5. DanTup commented on Jun 22, 2023

    @DanTup
    Member

    @bryanoltman are your issues resolved by the info above too, or are you still seeing anything unexpected/incorrect?

  6. bryanoltman commented on Jun 22, 2023

    @bryanoltman

    I'm not sure what the correct behavior is, but after explicitly setting my Flutter SDK path to /Users/bryanoltman/Documents/flutter/bin/flutter in dart.flutterSdkPaths, that is the only one I see in VS Code's Flutter: Change SDK menu. I'm not sure how the auto-detect logic works, but the issue seems to be resolved for now!

  7. DanTup commented on Jun 22, 2023

    @DanTup
    Member

    after explicitly setting my Flutter SDK path to /Users/bryanoltman/Documents/flutter/bin/flutter

    You shouldn't have bin/flutter on the end, these are paths to the SDKs, not to the binaries.

    that is the only one I see in VS Code's Flutter: Change SDK menu.

    If that's the only SDK in the dart.flutterSdkPaths setting, then it's expected that's the only one that shows up here. The Change SDK commands only ever looks at dart.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.flutterSdkPath setting.

  8. bryanoltman commented on Jun 22, 2023

    @bryanoltman

    Ack, sorry, I did not have /bin/flutter on the end – that was a copy/paste error on my side :)

  9. DanTup commented on Jun 23, 2023

    @DanTup
    Member

    So is everything working as expected now, or does something still seem wrong / confusing?

  10. felangel commented on Jun 23, 2023

    @felangel
    ContributorAuthor

    So is everything working as expected now, or does something still seem wrong / confusing?

    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.

  11. DanTup commented on Jun 26, 2023

    @DanTup
    Member

    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

    Got it - will fix that in #4608.

    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

    I'm not sure what you mean by "all Flutter installations". The "Change SDK" option will show you all SDKs it finds from the sdkPaths setting 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.

    it sounds like the extension picks an arbitrary one and I need to manually specify those in settings as dart.flutterSdkPaths

    Do you mean for the current session? The one used by the current session never comes from sdkPaths, only from sdkPath. When the extension loads, it tries to find an SDK by looking in a number of places (including the sdkPath setting, 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 sdkPaths setting 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 the sdkPath setting for the current workspace. Selecting "Auto Detect" will unset sdkPath for the current workspace, so the normal search will occur.

    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.

    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.

  12. yahu1031 commented on Aug 3, 2023

    @yahu1031

    Faced a similar issue. These logs may help - https://cdn.sourceb.in/bins/iq7NdMEOlt/0

  13. DanTup commented on Aug 7, 2023

    @DanTup
    Member

    @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!

  14. 1 remaining item

  15. DanTup commented on Aug 7, 2023

    @DanTup
    Member

    it takes the first sdk, i.e, .shorebird because it exists in the home dir.

    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 :-)

  16. eseidel commented on Feb 17, 2024

    @eseidel

    We continue to get customers hitting this issue, since shorebird release will 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 breaking flutter for the customer from within VSC. I guess we could write a shorebird repair command which found your system flutter and ran flutter pub get in your project directory and then asked you to restart your VSC terminal?

    I wonder how fvm deals with this.

  17. DanTup commented on Feb 17, 2024

    @DanTup
    Member

    I wonder how fvm deals with this.

    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).

    shorebird release will 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

    I don't think this is entirely a VS Code problem - the analyzer will also use .dart_tool/package_config.json to 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 on PATH but 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:

    1. Put some kind of .vscodeignore file 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)
    2. If we do the search both with and without package_config and get different results, we prompt the user that we found multiple Flutter SDKs in use with the project and ask the user to pick one, and write that into 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_config

    I 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?

  18. eseidel commented on Feb 17, 2024

    @eseidel

    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.

    1. I think this could work well, yes, but the analyzer confusion could remain. I believe the main problem for users is that the terminal points to the wrong flutter and they have no way to fix it (since they can't even easily get the path to the correct flutter to run to update their .dart_tool cache).
    2. I'm not sure how many users would see this. This might end up prompting users way more often than you'd want.

    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 (and dart) 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.

  19. DanTup commented on Feb 17, 2024

    @DanTup
    Member

    Users seem to still sometimes hit this (maybe control-C isn't caught by the finally)

    You could try something like ProcessSignal.sigint.watch().listen() (and maybe also sigterm?) 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).

    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?)

    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.

  20. eseidel commented on Feb 17, 2024

    @eseidel

    Yeah, we'd love to be able to run our version of flutter w/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.

  21. DanTup commented on Feb 17, 2024

    @DanTup
    Member

    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.

  22. markymakes-dev commented on Apr 8, 2024

    @markymakes-dev

    Is this issue solved? I just encounter this one.

  23. DanTup commented on Apr 8, 2024

    @DanTup
    Member

    @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_config to 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).

  24. manav828 commented on Dec 10, 2024

    @manav828

    1733845159562_shorebird.log
    image
    why my preview not build

  25. DanTup commented on Dec 10, 2024

    @DanTup
    Member

    @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!

  26. DanTup commented on Jul 2, 2026

    @DanTup
    Member

    FYI, in #6109 I'm demoting .dart_tool/package_config.json to below PATH in the SDK search order. If the SDK we select (eg. from PATH) is not the same as the one in .dart_tool/package_config.json (which would result in differences between the version of package:flutter that the analysis server is using and the one we will trigger flutter commands in), you'll see the usual popup that tells you packages are missing or out-of-date and encouraging you to re-run pub get.

  27. added this to the v3.140.0 milestone on Jul 2, 2026
  28. added
    in flutterRelates to running Flutter apps
    and removed on Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    in flutterRelates to running Flutter apps

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions