Repository navigation
Description
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.
- Affected: Windows only, stable
3.29.0through current stable3.41.7, andmaster(verified at b79192e 2026-06-11, re-verified at dd2d0ff 2026-06-12) - Introduced by: bc4fc5f ([ Tool ] Fix "Error: Unable to find git in your PATH" when Command Processor
AutoRunregistry key is defined #159424, merged 2024-12-02) - Fix: one character (
$git→git)
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):
- Run any
fluttercommand once so the tool snapshot andbin\cache\flutter_tools.stampare (re)built byshared.bat. - Inspect the stamp from cmd.exe:
type C:\path\to\flutter\bin\cache\flutter_tools.stamp - Run the exact command that
shared.batline 75 executes insideFOR /f:cmd /c "PUSHD C:\path\to\flutter & $git rev-parse HEAD"
- (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 whatshared.shproduces 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
":"(bytes22 3A 22 0D 0A) on every Windows machine. - Step 3:
(nonzero exit code)
'$git' is not recognized as an internal or external command, operable program or batch file. - 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%"$gitis not valid cmd.exe syntax —$-prefixed names mean nothing to the command processor, so the spawned shell looks for an executable literally named$gitand fails with'$git' is not recognized ….FOR /fcaptures only stdout; the error goes to stderr, which the enclosing2>NUL (block (line 67) discards. The loop body never executes and nothing is reported.revisionis therefore never set — it expands to empty (or, if the parent shell happens to export an environment variable namedrevision, to that unrelated value), so line 79 degenerates tocompilekey = ":".- 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. (TheFLUTTER_TOOL_ARGShalf 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 theengine-dart-sdk.stampcheck (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_toolson 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
Fix $git typo in shared.bat that broke Windows cache invalidation
Albarinor commentedon Aug 18, 2026
Additional Windows verification
I independently reproduced the
$gittypo on Windows with Flutter 3.44.9 stable. The checkout had Git available atC:\Program Files\Git\cmd\git.exe, andgit rev-parse HEADworked when invoked directly. However, the command embedded inbin/internal/shared.batfailed:Changing only
$gittogitmade the command return the framework revision. This is independent of the engine-version file itself:bin/internal/engine.versionandbin/cache/engine.stampwere both present and matched.In the same investigation, I found a separate Windows failure mode that produced the same generic Flutter message.
where PowerShell.exeresolved first to a zero-byte ordinary file: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.exeresolve 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
$gitcommand 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.[flutter_tools] Fix $git typo in shared.bat to restore cache invalida…
github-actions commentedon Sep 8, 2026
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.