Skip to content

CI: all Windows builds fail with exit 127 - hardcoded VS 2022 MSBuild path missing on windows-latest #4178

Description

@VeqtaDev

What happened?

Every Windows job of the PR validation workflow (Build / FiveM, Build / RedM, Build / Server) fails before a single translation unit is compiled.

.github/workflows/ci/build_windows.sh invokes MSBuild through a hardcoded path:

"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\MsBuild.exe" CitizenMP.sln ...

ci_build.yml runs these jobs on runs-on: windows-latest, and that label now resolves to the windows-2025-vs2026 runner image (Visual Studio 2026), so the VS 2022 path no longer exists:

.github/workflows/ci/build_windows.sh: line 8: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\MsBuild.exe: No such file or directory
.github/workflows/ci/build_windows.sh: line 20: errors.log: No such file or directory
##[error]Failed to build rdr3, MSBuild returned with error code: 127

Exit code 127 is the shell's "command not found", so the failure happens before MSBuild runs. Project generation itself succeeds — the log shows Generated build/rdr3/*.vcxproj ... Done (14369ms) immediately before the error — because code/tools/fxd/gen.ps1 already locates Visual Studio dynamically with the bundled code/tools/ci/vswhere.exe. Only the MSBuild invocation is hardcoded.

Runner image reported in the logs:

Image: windows-2025-vs2026
Version: 20260824.214.3

Expected result

Windows build jobs locate MSBuild on the runner and compile, so PR validation reflects the state of the code under review.

Reproduction steps

  1. Open a pull request touching any path that requires compilation (anything under code/, or an ext/native-decls/*.md file).
  2. Wait for the Validate PR workflow to reach Build / FiveM, Build / RedM and Build / Server.
  3. Every Windows job fails in the Compile step with exit code 127.

Scope

This is not specific to one PR. Across the last 100 Validate PR runs (2026-08-06 → 2026-09-07), no Windows build has succeeded. The only runs reporting success are those where input_validation determined no compilation was required and the Build job was skipped.

Because post_build applies the invalid label whenever any needed job fails, every PR that touches a compiled path is currently labelled invalid regardless of its contents.

Examples: 34147689136, 34103382485, 33561136821.

Area(s)

FiveM, RedM, FXServer — CI only, no runtime impact.

Specific version(s)

master @ 0d8a2a6, and every run in the window above.

Additional information

Two possible directions, both one-liners:

  1. Resolve MSBuild with the vswhere binary already vendored in this repo, mirroring what gen.ps1 does, so the script stops caring which VS version the image ships:

    MSBUILD=$(./code/tools/ci/vswhere.exe -prerelease -latest -products '*' \
        -requires Microsoft.Component.MSBuild \
        -find 'MSBuild\**\Bin\MSBuild.exe' | head -1)

    (resolved before the cd into code/build/..., then invoked as "$MSBUILD")

  2. Pin the runner to windows-2022 in ci_build.yml, restoring the previous environment exactly.

Option 1 is the more durable fix, but it moves the build onto whatever toolset the image ships; I have no way to verify from outside whether this codebase compiles cleanly under the VS 2026 toolset with systemversion '10.0.22000.0'. Option 2 is guaranteed to restore the previously working environment but will need revisiting when that image is retired. Happy to open a PR for whichever you prefer.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    RedMIssues/PRs related to RedMtriageNeeds a preliminary assessment to determine the urgency and required action

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions