Repository navigation
Description
Steps to reproduce
The google_fonts library tracks ongoing font loads in a global Set<Future<void>> pendingFontFutures. This set is used by GoogleFonts.pendingFonts() to await all active requests. In the current implementation, futures are removed from this set using .then(...). However, in Dart, the .then callback only executes on successful completion. If a font load fails (e.g., due to a 404 error or network timeout), the future is never removed from the set.
Since GoogleFonts.pendingFonts() performs a Future.wait() on the entire set, it will immediately re-throw the original error every time it is called, as long as the failed future remains in memory. This leads to "poisoned" states where a single failure breaks all subsequent font synchronization.
- Trigger a background font load that is guaranteed to fail (e.g., using a mock client that returns an error).
- Await GoogleFonts.pendingFonts() and catch the exception.
- Call GoogleFonts.pendingFonts() a second time.
The fix is to use
// In lib/src/google_fonts_base.dart
// Change this:
loadingFuture.then((_) => pendingFontFutures.remove(loadingFuture));
// To this:
loadingFuture
.whenComplete(() => pendingFontFutures.remove(loadingFuture))
.catchError((_) {});Expected results
The second call to pendingFonts() should succeed (or return a new set of results) because the previously failed load has finished and should have been cleared.
Actual results
The second call (and all subsequent calls) immediately throws the original exception because the failed future is still present in the tracking set.
Code sample
Code sample
Because we can't mock the http client from outside the package, this is not a flutter create bug but instead a test case inside the package:
test('pendingFonts() cleans up failed futures', () async {
await overridePrint(() async {
// Mock a failure.
when(mockHttpClient.gets(any)).thenThrow(Exception('Network failure'));
// Trigger a font load.
GoogleFonts.abel();
// The first call to pendingFonts() should throw the error.
try {
await GoogleFonts.pendingFonts();
fail('Should have thrown');
} catch (e) {
expect(e.toString(), contains('Network failure'));
}
// BUG: If fixed with .whenComplete, pendingFontFutures should be empty now.
// If using .then, the failed future is still there.
expect(
pendingFontFutures,
isEmpty,
reason: 'failed futures should be removed from the pending set',
);
// Subsequent calls will now throw the exception, forever.
await GoogleFonts.pendingFonts();
});
});Screenshots or Video
Screenshots / Video demonstration
N/A
Logs
Logs
N/A
Flutter Doctor output
Doctor output
❯ flutter doctor -v
[✓] Flutter (Channel stable, 3.41.0, on macOS 26.2 25C56 darwin-arm64, locale en-GB) [356ms]
• Flutter version 3.41.0 on channel stable at /opt/homebrew/share/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 44a626f4f0 (4 days ago), 2026-02-10 10:16:12 -0800
• Engine revision 3452d735bd
• Dart version 3.11.0
• DevTools version 2.54.1
• 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
[!] Android toolchain - develop for Android devices (Android SDK version 34.0.0) [2.1s]
• Android SDK at /Users/bramp/Library/Android/sdk
• Emulator version 36.3.10.0 (build_id 14472402) (CL:N/A)
✗ Flutter requires Android SDK 36 and the Android BuildTools 28.0.3
To update the Android SDK visit https://flutter.dev/to/macos-android-setup for detailed instructions.
• All Android licenses accepted.
[!] Xcode - develop for iOS and macOS (Xcode 26.2) [985ms]
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 17C52
! iOS 26.2 Simulator not installed; this may be necessary for iOS and macOS development.
To download and install the platform, open Xcode, select Xcode > Settings > Components,
and click the GET button for the required platform.
For more information, please visit:
https://developer.apple.com/documentation/xcode/installing-additional-simulator-runtimes
• CocoaPods version 1.16.2
[✓] Chrome - develop for the web [6ms]
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Connected device (2 available) [6.3s]
• macOS (desktop) • macos • darwin-arm64 • macOS 26.2 25C56 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 145.0.7632.75
[✓] Network resources [315ms]
• All expected network resources are available.
! Doctor found issues in 2 categories.
Activity
saurabh-mirajkar commentedon Feb 20, 2026
@bramp Thanks for a detailed report. Labelling it for further investigation.
[google_fonts] Remove failed loads from pendingFonts (#12240)
github-actions commentedon Aug 15, 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.