Skip to content

$git typo in bin/internal/shared.bat makes the flutter_tools stamp always ":" - git-revision cache invalidation has never worked on Windows since 3.29 #187907

Closed

Description

@kanta13jp1

Is there an existing issue for this?

Searched open and closed issues for shared.bat, flutter_tools.stamp, compilekey, "is not recognized" shared.bat, shared.bat revision, and stamp invalidation windows (last full sweep 2026-06-12, including all PRs touching shared.bat) — no existing report and no pending fix. Closest related issues are #159018 (the issue whose fix introduced this bug), #169784/#169794 (moved the WHERE git presence check to flutter.bat — adjacent code, different problem), and #94892 (which added FLUTTER_TOOL_ARGS to the stamp).

Summary

bin/internal/shared.bat computes the framework git revision with PowerShell-style syntax ($git) that cmd.exe cannot execute. The command fails on every Windows machine, the failure is silenced by a 2>NUL block, revision stays empty, and the compile key written to / compared against bin\cache\flutter_tools.stamp degenerates to the constant ":". Since a constant always equals itself, the git-revision-based invalidation of the flutter_tools snapshot has never worked on Windows since stable 3.29.0 (Dec 2024 on master). The bash counterpart shared.sh computes the revision correctly, so .bat also diverges from the cross-platform contract stated in both file headers.

Steps to reproduce

On 64-bit Windows with a stock git-based Flutter install ≥ 3.29 (verified on 3.41.7 stable, framework revision cc0734ac716fbb8b90f3f9db8020958b1553afa7, clean git status):

  1. Run any flutter command once so the tool snapshot and bin\cache\flutter_tools.stamp are (re)built by shared.bat.
  2. Inspect the stamp from cmd.exe:
    type C:\path\to\flutter\bin\cache\flutter_tools.stamp
  3. Run the exact command that shared.bat line 75 executes inside FOR /f:
    cmd /c "PUSHD C:\path\to\flutter & $git rev-parse HEAD"
  4. (Cross-check) Repeat step 2 on macOS/Linux with the same Flutter version.

Expected results

  • Step 2: the stamp contains the revision-bearing compile key, e.g. "cc0734ac716fbb8b90f3f9db8020958b1553afa7:" — which is exactly what shared.sh produces on macOS/Linux (step 4).
  • Step 3: prints the HEAD revision.
  • Consequence: changing the checked-out framework revision (bisect, branch switch, local tool patch) invalidates the cached flutter_tools snapshot, as it does on POSIX platforms.

Actual results

  • Step 2: the stamp is the literal three characters ":" (bytes 22 3A 22 0D 0A) on every Windows machine.
  • Step 3:
    '$git' is not recognized as an internal or external command,
    operable program or batch file.
    
    (nonzero exit code)
  • The revision-based invalidation can never fire: ":" is compared against ":" forever. No error is ever shown.

Root cause

bin/internal/shared.bat lines 66–79 (line numbers identical on master and 3.41.7):

  REM Get the Git revision.
  2>NUL (
    REM 'FOR /f' spawns a new terminal instance to run the command. If an
    REM 'AutoRun' command is defined in the user's registry, that command could
    REM change the working directory, and then we wouldn't be in the directory
    REM we expect to be in. To prevent this, we need to 'PUSHD %FLUTTER_ROOT%'
    REM before getting the git revision.
    REM
    REM See https://github.com/flutter/flutter/issues/159018
    FOR /f %%r IN ('PUSHD %FLUTTER_ROOT% ^& $git rev-parse HEAD') DO (
      SET revision=%%r
    )
  )
  SET compilekey="%revision%:%FLUTTER_TOOL_ARGS%"
  1. $git is not valid cmd.exe syntax — $-prefixed names mean nothing to the command processor, so the spawned shell looks for an executable literally named $git and fails with '$git' is not recognized ….
  2. FOR /f captures only stdout; the error goes to stderr, which the enclosing 2>NUL ( block (line 67) discards. The loop body never executes and nothing is reported.
  3. revision is therefore never set — it expands to empty (or, if the parent shell happens to export an environment variable named revision, to that unrelated value), so line 79 degenerates to compilekey = ":".
  4. That degenerate key is written to bin\cache\flutter_tools.stamp (line 229) and compared on every launch (lines 98–99). The comparison can never differ, so the revision check is dead code. (The FLUTTER_TOOL_ARGS half of the key still functions.)

The bash counterpart computes the revision correctly (shared.sh lines 124–125):

local revision="$(cd "$FLUTTER_ROOT"; git rev-parse HEAD)"
local compilekey="$revision:$FLUTTER_TOOL_ARGS"

Both files carry a header note saying their logic must be kept consistent across platforms; the .bat currently violates that contract.

Where it was introduced

Commit bc4fc5f (#159424, merged 2024-12-02), which reworked this block to fix #159018 (spurious "Unable to find git in your PATH" when a Command Processor AutoRun registry key is defined):

-    PUSHD "%flutter_root%"
-    FOR /f %%r IN ('git rev-parse HEAD') DO (
-      SET git_exists=true
+    FOR /f %%r IN ('PUSHD %FLUTTER_ROOT% ^& $git rev-parse HEAD') DO (
       SET revision=%%r
     )
-    POPD

$git appears to be an editing leftover. Because that PR also moved git-presence detection to a separate WHERE git check, the user-visible error it was fixing went away — and the revision lookup silently died at the same time.

Release timeline:

ref revision lookup checked
3.24.0 / 3.27.0 'git rev-parse HEAD' — works file content at tag
3.29.0 (first affected) 'PUSHD %FLUTTER_ROOT% ^& $git rev-parse HEAD' file content at tag (line 69)
3.41.7 (current stable) same, line 75 empirically on a clean install
master @ b79192e (2026-06-11) same, line 75 file content
master @ dd2d0ff (2026-06-12) same, line 75 file content at pinned SHA

Impact

Largely masked in everyday use, which is why it has survived ~18 months:

  • Normal flutter upgrade / channel switches almost always change the engine content hash, and the engine-dart-sdk.stamp check (lines 92–95) then forces the Dart SDK update path, which rebuilds the tool snapshot anyway.
  • The pubspec.yaml-newer-than-pubspec.lock check (lines 100–106) catches some further cases.

It bites whenever the framework revision changes without an engine change and without a flutter_tools pubspec change:

  • bisecting or checking out framework commits between engine rolls inside the SDK — the tool keeps running the previous revision's snapshot;
  • developing or locally patching flutter_tools on Windows;
  • forks/pins that share an engine version.

In those cases Windows silently runs a stale flutter_tools, diverging from macOS/Linux behavior, and the staleness is hard to attribute (deleting bin\cache "fixes" it, which further hides the root cause). The 2>NUL design also means any future breakage of this command line would be equally invisible — worth a comment or a smoke check.

Suggested fix

One character — drop the $:

    FOR /f %%r IN ('PUSHD %FLUTTER_ROOT% ^& git rev-parse HEAD') DO (

(git presence is already guaranteed before this point: flutter.bat checks WHERE git since #169794. While touching the line, PUSHD "%FLUTTER_ROOT%" could also be quoted, as the pre-#159424 code did.)

Note: the first run after this fix lands will rebuild the flutter tool once on every Windows machine, because the stored stamp ":" no longer matches the real compile key. That is expected and harmless.

Given it is a one-character, Windows-only launcher-script fix, this may also be a good cherry-pick candidate for a stable hotfix.

Code sample / Screenshots

N/A (SDK launcher script bug — no Dart code involved).

Logs

Verification transcript (Windows 11, stock Flutter 3.41.7 stable)
PS> cmd /c ver
Microsoft Windows [Version 10.0.26200.8524]

PS> git -C C:\app\flutter rev-parse HEAD
cc0734ac716fbb8b90f3f9db8020958b1553afa7
PS> git -C C:\app\flutter describe --tags
3.41.7
PS> git -C C:\app\flutter status --porcelain
(no output - clean stock checkout)

PS> Get-Content C:\app\flutter\bin\cache\flutter_tools.stamp -Raw
":"

PS> Format-Hex C:\app\flutter\bin\cache\flutter_tools.stamp
           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000   22 3A 22 0D 0A                                   ":"..

# The exact command shared.bat line 75 runs inside FOR /f:
PS> cmd /c 'PUSHD C:\app\flutter & $git rev-parse HEAD'
'$git' is not recognized as an internal or external command,
operable program or batch file.
# exit code: 1

# Control - same command with plain `git`:
PS> cmd /c 'PUSHD C:\app\flutter & git rev-parse HEAD'
cc0734ac716fbb8b90f3f9db8020958b1553afa7
# exit code: 0

Flutter Doctor output

flutter doctor -v

Run with CI=true set; username redacted.

[√] Flutter (Channel stable, 3.41.7, on Microsoft Windows [Version 10.0.26200.8655], locale ja-JP)
    • Flutter version 3.41.7 on channel stable at C:\app\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision cc0734ac71 (8 weeks ago), 2026-04-15 21:21:08 -0700
    • Engine revision 59aa584fdf
    • Dart version 3.11.5
    • DevTools version 2.54.2
    • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations, enable-native-assets, omit-legacy-version-file, enable-lldb-debugging, enable-uiscene-migration

[√] Windows Version (11 Home 64-bit, 25H2, 2009)

[X] Android toolchain - develop for Android devices
    X Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/to/windows-android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.

[√] Chrome - develop for the web
    • CHROME_EXECUTABLE = C:\Users\<user>\scoop\apps\googlechrome\current\chrome.exe

[X] Visual Studio - develop Windows apps
    X Visual Studio not installed; this is necessary to develop Windows apps.
      Download at https://visualstudio.microsoft.com/downloads/.
      Please install the "Desktop development with C++" workload, including all of its default components

[√] Connected device (3 available)
    • Windows (desktop) • windows • windows-x64    • Microsoft Windows [Version 10.0.26200.8655]
    • Chrome (web)      • chrome  • web-javascript • Google Chrome 149.0.7827.103
    • Edge (web)        • edge    • web-javascript • Microsoft Edge 149.0.4022.62

[√] Network resources
    • All expected network resources are available.

! Doctor found issues in 2 categories.

(The two [X] entries — Android SDK and Visual Studio not installed — are unrelated to this report; the bug reproduces in shared.bat before the tool runs.)

bin/cache/flutter.version.json of the verified install:

{
  "frameworkVersion": "3.41.7",
  "channel": "stable",
  "repositoryUrl": "https://github.com/flutter/flutter.git",
  "frameworkRevision": "cc0734ac716fbb8b90f3f9db8020958b1553afa7",
  "frameworkCommitDate": "2026-04-15 21:21:08 -0700",
  "engineRevision": "59aa584fdf100e6c78c785d8a5b565d1de4b48ab",
  "engineCommitDate": "2026-04-16 02:32:16.000Z",
  "engineContentHash": "7a53c052bc4b472cf780b199087e1368e4a9aa8c",
  "engineBuildDate": "2026-04-16 12:00:22.023",
  "dartSdkVersion": "3.11.5",
  "devToolsVersion": "2.54.2",
  "flutterVersion": "3.41.7"
}

Activity

  1. added
    toolAffects the "flutter" command-line tool. See also t: labels.
    team-toolOwned by Flutter Tool team
    on Jun 12, 2026
  2. added
    P1High-priority issues at the top of the work list
    triaged-toolTriaged by Flutter Tool team
    on Jun 23, 2026
  3. Albarinor commented on Aug 18, 2026

    @Albarinor

    Additional Windows verification

    I independently reproduced the $git typo on Windows with Flutter 3.44.9 stable. The checkout had Git available at C:\Program Files\Git\cmd\git.exe, and git rev-parse HEAD worked when invoked directly. However, the command embedded in bin/internal/shared.bat failed:

    PUSHD %FLUTTER_ROOT% & $git rev-parse HEAD

    Changing only $git to git made the command return the framework revision. This is independent of the engine-version file itself: bin/internal/engine.version and bin/cache/engine.stamp were both present and matched.

    In the same investigation, I found a separate Windows failure mode that produced the same generic Flutter message. where PowerShell.exe resolved first to a zero-byte ordinary file:

    C:\Windows\System32\powershell.exe       0 bytes
    C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe   valid
    

    The real Windows PowerShell executable worked when invoked by its fully qualified path, while the PATH-first zero-byte file failed. Removing/quarantining the invalid file made where PowerShell.exe resolve to the valid executable and allowed the unmodified Flutter launcher to run normally.

    This suggests the error message can wrap at least two different launcher/bootstrap failures: the $git command typo and failure to execute the selected PowerShell executable. Reporting the underlying command and resolved executable would make this class of failure substantially easier to diagnose.

  4. github-actions commented on Sep 8, 2026

    @github-actions

    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 -v and a minimal reproduction of the issue.

  5. locked as resolved and limited conversation to collaborators on Sep 8, 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

    P1High-priority issues at the top of the work listteam-toolOwned by Flutter Tool teamtoolAffects the "flutter" command-line tool. See also t: labels.triaged-toolTriaged by Flutter Tool team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions