Skip to content

Prefer Flutter SDK from PATH before one read from a .dart_tool/package_config.json #5844

Closed

Description

@PaulGrandperrin

Describe the bug
I am managing Dart/Flutter SDKs with nix and direnv, but the same issue also happens when manually managing SDKs.

When I change my SDK for a project (using nix or manually), I change 3 env vars:

  • PATH
  • DART_ROOT
  • FLUTTER_ROOT

to point to their respective directories in the flutter SDK.

This works perfectly for the command line and for the first time VSCode opens the project.

The issue is that when I change those env vars and VSCode had already opened the project before, it'll continue to use the previous SDK.

This is because the path to the previous SDK is stored in .dart_tool/package_config.json and is used in priority to the 3 env vars I set.

Deleting this file forces VSCode to use the 3 env vars but will unfortunately recreate this file with the new paths hardcoded again.

@DanTup explained why the current behavior exists: dart-lang/sdk#52947 (comment)

Expected behavior
VSCode should always use the paths from those env vars and never store those paths because they might get out of sync with the user choice of SDK.

  • Operating System and version: NixOS 25.11
  • VS Code version: 1.106.3
  • Dart extension version: 3.124.1
  • Dart/Flutter SDK version: 3.40.0-0.1.pre

Activity

  1. DanTup commented on Dec 12, 2025

    @DanTup
    Member

    VSCode should always use the paths from those env vars and never store those paths because they might get out of sync with the user choice of SDK.

    It's not VS Code storing these paths, it's Dart/pub. When you run flutter packages get, pub will resolve dependencies, download them to the pub cache (if they're not local), and then write .dart_tool/package_config.json with all of the resolution data.

    When you run a script with dart foo.dart, it is this file where Dart looks to know how to resolve any package: imports. Things are a bit different for dart run and flutter run, because I think they will always force a pub get to run, so this file will be re-resolved. However, if we just ignore this file then we might end up running your app with a different Flutter SDK compared to the one the analysis server is using to resolve package:flutter.

    A simplified version of what we do at startup (for a Flutter project) is this:

    • Check whether the user has configured a dart.flutterSdkPath
    • Check whether we can locate the Flutter SDK being used from the .dart_tool/package_config.json file
    • Check whether we can find a Flutter SDK on PATH

    We can't completely ignore the .dart_tool/package_config.json file for the reasons above, but I wonder if instead of using it for the SDK, we could just read it and verify whether it matches the SDK we would others pick, and if there is a mismatch, show a prompt (similar to when packages are out of date)?

    It does mean that you might get spurious errors initially (because your analysis server will be using the location from .dart_tool/package_config.json), but as long as you accept the prompt to let it run flutter pub get, it should then fix those references.

  2. DanTup commented on Dec 12, 2025

    @DanTup
    Member

    @eseidel I wonder if this would help Shorebird too? I recall you had some issues where package_config.json would be pointing at an odd SDK you didn't really want us to use, but it's where the analyzer would be looking. Perhaps if instead of using the path from there, we instead warn that it's wrong and offer to fix it (by just running pub get from whatever other SDK we selected by ignoring that path), things would work as you'd like (at the expensive of one prompt + user action each time it needs to be "fixed").

  3. PaulGrandperrin commented on Dec 12, 2025

    @PaulGrandperrin
    Author

    I'm using the direnv-vscode extension (https://github.com/direnv/direnv-vscode) and whenever I change the nix file describing my dependencies, it automatically reloads everything in vscode's workspace, which I think probably includes dart's analyzer.

    Thanks to this, everything is usually in sync between my nix file, the terminal env and vscode, including its extensions.

    Now I understand how .dart_tool/package_config.json can be useful, but in this use-case, it seems like it actually go in the way of having dart extensions correctly synchronized with the rest of the IDE.

  4. PaulGrandperrin commented on Dec 12, 2025

    @PaulGrandperrin
    Author

    I'm realizing that the link between nix and direnv is probably not obvious for non nix using people.
    More info so everything is clear:

    • nix: basically, a build system that build / fetch / patch dependencies in and provides the paths to the built artifacts as env vars
    • direnv: a small command-line tool that automatically loads some env vars when cding in a project's directory
    • nix-direnv: connects the two together
    • direnv-vscode: like direnv, but automatically reload the vscode workspace with the new env vars instead of just the terminal
  5. DanTup commented on Dec 12, 2025

    @DanTup
    Member

    @PaulGrandperrin I'm looking at the code in that extension, and I can see that it updates the env variables for the extension host process, but it also looks like it restarts the extension host, so I'm not sure if they'd presist.

    Could you try running the Dart: Open Extension Log command and looking for:

    [17:21:37] [General] [Info] Environment PATH:
    

    And confirm the expected paths are listed. Then try changing the PATH with direnv, and then re-opening the extension log, and checking whether it sees the updated values?

    If it does, then I think my suggestion above may help. If not, I'm not sure what options we have.

  6. PaulGrandperrin commented on Dec 12, 2025

    @PaulGrandperrin
    Author

    @DanTup I just tried and looking at the logs, the dart extension is fully restarted and it shows the updated PATH.

    Also! After being restarted, the dart extensions showed me a notification saying something like "Some packages are missing or out of date" with a button "pub get".

    I probably saw it before but ignored it because after updating the SDK my intuition was to first validate that my project was still working before updating anything else that might cause unrelated issues.

    So, I think that what you were suggesting already exists?

    I really didn't realize that "pub get" was necessary for the vscode extension to use the new SDK.

  7. DanTup commented on Dec 12, 2025

    @DanTup
    Member

    I just tried and looking at the logs, the dart extension is fully restarted and it shows the updated PATH.

    Great!

    Also! After being restarted, the dart extensions showed me a notification saying something like "Some packages are missing or out of date" with a button "pub get".

    So, I think that what you were suggesting already exists?

    It does, but it currently is showing only when those files appear out-of-date, and we may still have selected the wrong SDK for you. Eg., if you accept that prompt and run pub get, then change to a different path using your direnv, I think it will just restart and continue using the "old" SDK (because we read it from .dart_tool/package_config.json).

    My proposal is to:

    1. Move .dart_tool/package_config.json BELOW the env PATH in the SDK search order
    2. Detect if dart_tool/package_config.json points to a different SDK to the one we selected, and if so show the same prompt (although with a slightly different message)

    It will still rely on you noticing the prompt and clicking the button though.

  8. PaulGrandperrin commented on Dec 12, 2025

    @PaulGrandperrin
    Author

    It seems like a good plan to me :)

    About the notification, to be clear, my mistake wasn't that I didn't notice it but that its message wasn't explicit about the fact that pub get was needed for the IDE to use the new SDK.

  9. added this to the On Deck milestone on Jan 20, 2026
  10. added
    is enhancementAn enhancement or improvement that should be listed in release notes but is not a bug fix.
    in flutterRelates to running Flutter apps
    and removed on Jan 20, 2026
  11. DanTup commented on Jul 2, 2026

    @DanTup
    Member

    It turns out, we would already prompt to re-run pub get if the SDK paths mismatched. We also prompt if the versions are different (which I expect will covert many cases where the paths are different, since the most common reason to have multiple SDKs is different versions).

    So the only thing necessary here is to swap the search order so that .dart_tool/package_config.json comes after PATH.

  12. modified the milestones: On Deck, v3.140.0 on Jul 2, 2026
  13. self-assigned this
    on Jul 2, 2026
  14. changed the title [-]VSCode keeps using previous dart/flutter SDK after upgrade (out of date .dart_tool/package_config.json)[/-] [+]Prefer Flutter SDK from PATH before one read from a `.dart_tool/package_config.json`[/+] 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

Labels

in flutterRelates to running Flutter appsis enhancementAn enhancement or improvement that should be listed in release notes but is not a bug fix.

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions