[5.8][Mac] "Failed to finalize the .app with Xcode" on Xcode 27: xcodebuild started without stdin (Bad file descriptor in "Touch UBT generated tiles")

Summary

[Mac] Game targets fail at “Failed to finalize the .app with Xcode” on Xcode 27: the xcodebuild launched by the ApplePostBuildSync action starts with stdin (fd 0) closed, and Xcode 27 cannot launch the scheme pre-action “Touch UBT generated tiles” (“Failed to launch task /bin/sh: … Bad file descriptor”).

What Type of Bug are you experiencing?

Other

Steps to Reproduce

  1. On a Mac with macOS 27.0.1 (26A434) and Xcode 27.0 (27A266a), make Xcode the active developer directory (sudo xcode-select --switch /Applications/Xcode.app) and install the Metal Toolchain (xcodebuild -downloadComponent MetalToolchain).
  2. Install Unreal Engine 5.8.3 from the Epic Games Launcher.
  3. Copy the engine’s C++ blank template (Templates/TP_Blank) to any folder, unchanged, no plugins.
  4. From Terminal, build the game target:
    Engine/Build/BatchFiles/Mac/Build.sh TP_Blank Mac Development -Project=/TP_Blank.uproject
    or package it:
    RunUAT.sh BuildCookRun -project=/TP_Blank.uproject -platform=Mac -clientconfig=Development -build -cook -stage -package -pak -archive -archivedirectory=

Expected Result

The game target compiles and links, the ApplePostBuildSync action finalizes Binaries/Mac/TP_Blank.app with Xcode, UBT writes the receipt (Binaries/Mac/TP_Blank.target), and BuildCookRun goes on to cook, stage, package and archive the game.

Observed Result

Compiling and linking succeed, then the ApplePostBuildSync action fails, on every attempt:

[334/335] ApplePostBuildSync Executing PostBuildSync […/Binaries/Mac/TP_Blank] [NoUba]
Run pre-actions
SchemeAction Touch\ UBT\ generated\ tiles /var/folders/…/T/SchemeScriptAction-XXXXXX.sh
** BUILD FAILED **
The following build commands failed:
Run custom shell script ‘Touch UBT generated tiles’
ERROR: Failed to finalize the .app with Xcode. Check the log for more information
Result: Failed (OtherCompilationError)
AutomationTool exiting with ExitCode=6 (6)

The UBT log shows nothing else. The Xcode activity log (~/Library/Developer/Xcode/DerivedData/TP_Blank_Mac_TP_Blank-/Logs/Build/.xcactivitylog) has the actual error:

Failed to launch task /bin/sh: The operation couldn’t be completed. Bad file descriptor

The receipt is never written, so “BuildCookRun -skipbuild” afterwards fails with “Missing receipt ‘…/Binaries/Mac/TP_Blank.target’”. No project with game code can be packaged for Mac.

Affects Versions

5.8

Platform(s)

Mac

Additional Notes

Very likely the same issue as this thread (UE 5.8.2, macOS 27, Xcode 27, same “Touch UBT generated tiles” pre-action failure, there on iOS): UE5.8 Unable to build Game on macOS 27 - #6 by Mealtris
It also explains why building from the Xcode IDE works there: the IDE gives xcodebuild a valid stdin.

What I found:

  • lsof on the xcodebuild that UBT starts for PostBuildSync shows only fds 1 and 2 (pipes), no fd 0. Its parent, “UnrealBuildTool.dll -Mode=ApplePostBuildSync” (started by the executor), has a pipe on fd 0, but that stdin is not inherited by its child. The top-level UBT has a valid stdin (/dev/null or a TTY).
  • Running the exact xcodebuild command from the log’s “params:” line by hand succeeds with stdin from a terminal, from /dev/null or from a pipe, and fails the same way with stdin closed (“… <&-”): “Run custom shell script ‘Touch UBT generated tiles’”, BUILD FAILED, “Bad file descriptor” in the activity log.
  • Running the action by hand outside the executor succeeds:
    dotnet Engine/Binaries/DotNET/UnrealBuildTool/UnrealBuildTool.dll -Mode=ApplePostBuildSync -Input=/Intermediate/Build/Mac/arm64/TP_Blank/Development/PostBuildSync_TP_Blank.json -XmlConfigCache=/Intermediate/Build/XmlConfigCache.bin
  • -NoUBA does not help: in 5.8, ExecutorFactory always uses UBAExecutor, and -NoUBA only sets bAllowDetour = false.
  • Same failure from a real Terminal (TTY), from a background job, and with </dev/null given to Build.sh or RunUAT.sh.
  • Probable cause: AppleExports.BuildWithStubXcodeProject runs “/usr/bin/env … xcodebuild” with RedirectStandardOutput/Error and leaves stdin to be inherited, and in the executor’s process tree there is no inheritable stdin to inherit. Older Xcode versions presumably tolerated a closed stdin; Xcode 27 fails when it spawns the scheme pre-action.
  • Suggested fix: give xcodebuild an explicit stdin in BuildWithStubXcodeProject (for example RedirectStandardInput = true and close it, or open /dev/null), and/or have the UBA local executor pass an inheritable stdin to the processes it starts.
  • Confirmed workaround: make xcodebuild get a valid stdin. With DEVELOPER_DIR pointing at a mirror of Xcode.app/Contents/Developer (symlinks, inside a folder named *.app so xcrun accepts it) whose usr/bin/xcodebuild is a script running
    DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer exec /Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild “$@” </dev/null
    the build, cook, stage, package and archive all succeed, the packaged game runs, and codesign --verify --deep passes.

Environment: Mac mini M4 (16 GB), macOS 27.0.1 (26A434), Xcode 27.0 (27A266a) with Metal Toolchain 27A266a, Unreal Engine 5.8.3 (Launcher, CL 58210709), the engine’s bundled .NET 10.0.203.

This is fixed and will be in 5.8.4: