# Risk map — flutter/flutter

> Canonical page: https://codevetter.com/unpack/flutter/risk-map

# Risk map — flutter/flutter

Scanned commit acb8fd51143a49384799557cb1df6ecead61a55a (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

The biggest risk surface is the bootstrap supply chain: every fresh clone downloads and executes a Dart SDK and prebuilt engine artifacts over HTTPS, with host-overridable base URLs. Crash reporting and analytics exfiltrate command lines and stack traces (gated but present). Cross-platform shell logic is duplicated between .sh/.bat pairs that must be manually kept in sync. The locking scheme degrades to mkdir on NFS, and cache invalidation leans on file mtimes. The merged monorepo concentrates blast radius: .ci.yaml is ~7800 lines, DEPS pins a dozen external revisions, and 'isolated' files must not leak into google3 builds.
- Supply-chain: bin/internal/update_dart_sdk.sh downloads the Dart SDK from ${FLUTTER_STORAGE_BASE_URL:-https://storage.googleapis.com} at first run; cache.dart similarly downloads engine artifacts and CIPD packages from Google endpoints — a hostile mirror or MITM upstream would execute code on dev machines. — [bin/internal/update_dart_sdk.sh#L133-178](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/bin/internal/update_dart_sdk.sh#L133-L178) [packages/flutter_tools/lib/src/cache.dart#L537-590](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/packages/flutter_tools/lib/src/cache.dart#L537-L590)
- Telemetry exfiltration: runner.dart sends analytics events and, on crashes, sends a report containing the full command line, exception type, stack trace, and flutter doctor output via CrashReportSender — suppressed on bots and for --local-engine runs but on by default. — [packages/flutter_tools/lib/runner.dart#L290-340](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/packages/flutter_tools/lib/runner.dart#L290-L340) [packages/flutter_tools/lib/src/reporting/crash_reporting.dart](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/packages/flutter_tools/lib/src/reporting/crash_reporting.dart)
- dev/bots/serviceaccount.enc is an encrypted service-account blob committed to the repo — a secrets-adjacent file whose decryption path lives in CI infrastructure. — [dev/bots/serviceaccount.enc](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/dev/bots/serviceaccount.enc)
- Duplicated bootstrap logic: bin/flutter, flutter.bat, shared.sh, and shared.bat carry mirrored logic and header comments explicitly warn to keep them consistent — drift between them is a recurring hazard. — [bin/flutter#L6-12](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/bin/flutter#L6-L12) [bin/internal/shared.sh#L6-12](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/bin/internal/shared.sh#L6-L12) [bin/internal/shared.bat](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/bin/internal/shared.bat)
- Upgrade locking degrades gracefully but unevenly: flock -> shlock -> mkdir fallback; flock errors are swallowed (NFS needs write fds), and the mkdir lock relies on atomic directory creation, so concurrent first-runs on exotic filesystems can race. — [bin/internal/shared.sh#L46-113](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/bin/internal/shared.sh#L46-L113)
- Cache invalidation relies on pubspec.yaml-vs-pubspec.lock mtime comparison plus a hand-maintained compilekey (revision:FLUTTER_TOOL_ARGS); a NOP pub upgrade touches pubspec.lock (issue 171024 workaround) — subtle staleness bugs have occurred here. — [bin/internal/shared.sh#L34-36](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/bin/internal/shared.sh#L34-L36) [bin/internal/shared.sh#L124-146](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/bin/internal/shared.sh#L124-L146)
- Hot restart correctness depends on a filename-swapping hack (.swap dill) because Windows embedders memory-map the previous dill — fragile coupling between tool behavior and embedder file semantics. — [packages/flutter_tools/lib/src/run_hot.dart#L109-120](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/packages/flutter_tools/lib/src/run_hot.dart#L109-L120)
- google3 divergence: executable.main notes WebRunner/DevTools/mustache deps differ in google3 and files under lib/src/isolated are 'intentionally excluded from google3 tooling' — edits crossing that boundary break internal builds invisibly to OSS CI. (inferred) — [packages/flutter_tools/lib/executable.dart#L61-73](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/packages/flutter_tools/lib/executable.dart#L61-L73) [packages/flutter_tools/lib/executable.dart#L140-155](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/packages/flutter_tools/lib/executable.dart#L140-L155) [packages/flutter_tools/lib/src/isolated/build_targets.dart](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/packages/flutter_tools/lib/src/isolated/build_targets.dart)
- DEPS pins dart_revision, skia_revision, clang_version, reclient_version and more; comments warn that dart rolls must also update transitive deps via //tools/dart/create_updated_flutter_deps.py — manual edits produce skewed toolchains. — [DEPS#L30-60](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/DEPS#L30-L60)
- .ci.yaml is ~7847 lines declaring hundreds of LUCI targets with pinned dependency versions (android_sdk 37v2, open_jdk 21, multiple gradle dists) — a single malformed property breaks scheduling across the fleet. — [.ci.yaml#L31-80](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/.ci.yaml#L31-L80)
- The tool writes to shared mutable state in $FLUTTER_ROOT/bin/cache and only warns (with a paperclip) when run as root outside containers/CI — careless sudo usage corrupts the cache for the owning user. — [bin/internal/shared.sh#L221-227](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/bin/internal/shared.sh#L221-L227) [bin/internal/shared.sh#L118-120](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/bin/internal/shared.sh#L118-L120)
- Error-handling depth: _handleToolErrorImpl nests a catch-all inside the crash-report path and deliberately throws ProcessExit(immediate) to break potential infinite error loops — complex error semantics easy to regress. — [packages/flutter_tools/lib/runner.dart#L340-352](https://github.com/flutter/flutter/blob/acb8fd51143a49384799557cb1df6ecead61a55a/packages/flutter_tools/lib/runner.dart#L340-L352)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
