Skip to content

[stable] [flutter_tools] Handle missing Xcode gracefully in getInfo and buildMacOS - #191902

Merged
auto-submit[bot] merged 1 commit into
flutter:flutter-3.47-candidate.0from
bkonyi:cherry-pick-191180-to-stable
Sep 1, 2026
Merged

auto-submit[bot] merged 1 commit into
flutter:flutter-3.47-candidate.0from
bkonyi:cherry-pick-191180-to-stable

Conversation

@bkonyi

@bkonyi bkonyi commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

This pull request is created by automatic cherry pick workflow
Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request.

Issue Link:

#191176

Impact Description:

When running flutter build macos or flutter build ios on systems where Xcode is uninstalled, incomplete (e.g. Command Line Tools only), or misconfigured, XcodeProjectInterpreter.getInfo invokes xcrun xcodebuild -list which exits with code 72 (unable to find utility "xcodebuild"). Because code 72 was not in the allowed exit codes, flutter_tools crashes with an unhandled ProcessException. In Flutter 3.47.1 telemetry, this was a top crash with 320 crashes (15.2% share of top 10 crashes). This impacts development workflows on macOS.

Conflict Resolution Note: Resolved a minor merge conflict in packages/flutter_tools/lib/src/macos/build_macos.dart by ordering the Xcode installation pre-flight check ahead of workspace validation.

Changelog Description:

[flutter/191176] When building for macOS or iOS on machines with missing or incomplete Xcode installations, flutter_tools displays an actionable error message instead of crashing with an unhandled ProcessException.

Workaround:

Install Xcode or configure the active developer directory via:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer

Risk:

  • Low
  • Medium
  • High

Test Coverage:

  • Yes
  • No

Validation Steps:

  1. On a macOS machine, switch xcode-select to Command Line Tools: sudo xcode-select -s /Library/Developer/CommandLineTools.
  2. Run flutter build macos in a Flutter project.
  3. Verify flutter_tools displays a clean ToolExit instructing the user to install or configure Xcode, rather than crashing with an unhandled ProcessException and stack trace.
  4. Run automated test suite: dart test test/general.shard/ios/xcodeproj_test.dart and dart test test/commands.shard/hermetic/build_macos_test.dart.

…acOS (flutter#191180)

Fixes flutter#191176

In Flutter 3.47.0 telemetry, an unhandled `ProcessException` when
invoking `xcodebuild` emerged as a top crash signature. When running
`flutter build macos` on a machine where Xcode is not installed,
incomplete, or misconfigured, `flutter_tools` crashes with an unhandled
`ProcessException` instead of providing a graceful `ToolExit` error
message.

1. `buildMacOS` in
`packages/flutter_tools/lib/src/macos/build_macos.dart` lacked
pre-flight toolchain validation
(`globals.xcodeProjectInterpreter?.isInstalled != true`) before querying
Xcode project information.
2. In `XcodeProjectInterpreter.getInfo`
(`packages/flutter_tools/lib/src/ios/xcodeproj.dart`), `xcodebuild
-list` is executed with `throwOnError: true` while only allowing exit
codes 66 and 74. When `xcrun` returns exit code 72 (unable to find
utility "xcodebuild"), `_processUtils.run` throws an uncaught
`ProcessException`.
3. `buildMacOS` improperly used non-null assertions on `projectInfo!`
when resolving build schemes.

- Added pre-flight Xcode toolchain check in `buildMacOS` to exit early
with `globals.userMessages.xcodeMissing`.
- Wrapped `XcodeProjectInterpreter.getInfo` in a `try ... on
ProcessException` block to convert unexpected process failures to
user-friendly `ToolExit` messages.
- Added safe null checks on `projectInfo` in `buildMacOS`.
@bkonyi bkonyi added the cp: review Cherry-picks in the review queue label Aug 27, 2026
@bkonyi
bkonyi requested review from a team as code owners August 27, 2026 17:38
@bkonyi bkonyi added the cp: review Cherry-picks in the review queue label Aug 27, 2026
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Aug 27, 2026
@flutter-dashboard

Copy link
Copy Markdown

This pull request was opened from and to a release candidate branch. This should only be done as part of the official Flutter release process. If you are attempting to make a regular contribution to the Flutter project, please close this PR and follow the instructions at Tree Hygiene for detailed instructions on contributing to Flutter.

Reviewers: Use caution before merging pull requests to release branches. Ensure the proper procedure has been followed.

@github-actions github-actions Bot added platform-ios iOS applications specifically tool Affects the "flutter" command-line tool. See also t: labels. platform-macos Building on or for macOS specifically a: desktop Running on desktop team-ios Owned by iOS platform team team-macos Owned by the macOS platform team labels Aug 27, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request improves error handling when Xcode is missing or when retrieving Xcode project information fails. It adds an early check for Xcode installation during macOS builds, wraps the xcodebuild -list process call in a try-catch block to handle ProcessException, and updates tests accordingly. The review feedback suggests that the null check on projectInfo in build_macos.dart is redundant due to the early check and recommends simplifying it using null assertions.

Comment on lines +158 to +165
if (projectInfo == null) {
throwToolExit('Unable to get Xcode project information.');
}
final String? scheme = projectInfo.schemeFor(buildInfo);
if (scheme == null) {
projectInfo!.reportFlavorNotFoundAndExit();
projectInfo.reportFlavorNotFoundAndExit();
}
final String? configuration = projectInfo?.buildConfigurationFor(buildInfo, scheme);
final String? configuration = projectInfo.buildConfigurationFor(buildInfo, scheme);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since globals.xcodeProjectInterpreter is guaranteed to be non-null and installed due to the early exit check at the beginning of buildMacOS (line 89), projectInfo will never be null here. The if (projectInfo == null) check is dead code.

We can safely remove this check and instead use the null assertion operator projectInfo! on the first access. Dart's flow analysis will automatically promote projectInfo to a non-nullable type for all subsequent lines, keeping the code clean and avoiding unreachable error handling.

  final String? scheme = projectInfo!.schemeFor(buildInfo);
  if (scheme == null) {
    projectInfo.reportFlavorNotFoundAndExit();
  }
  final String? configuration = projectInfo.buildConfigurationFor(buildInfo, scheme);
References
  1. Optimize for readability: Code is read more often than it is written. (link)

@LouiseHsu
LouiseHsu requested a review from vashworth August 27, 2026 22:00

@justinmc justinmc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 . I re-ran some failed checks.

@justinmc justinmc added the autosubmit Merge PR when tree becomes green via auto submit App label Sep 1, 2026
@auto-submit
auto-submit Bot merged commit 115c53d into flutter:flutter-3.47-candidate.0 Sep 1, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: desktop Running on desktop autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD cp: review Cherry-picks in the review queue platform-ios iOS applications specifically platform-macos Building on or for macOS specifically team-ios Owned by iOS platform team team-macos Owned by the macOS platform team tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants