Unity-Technologies/UnityCsReference · error · InvalidOperationException

{toolName} does not appear to be built in {il2CppFolder}

Error message

{toolName} does not appear to be built in {il2CppFolder}

What it means

Thrown when locating an IL2CPP tool (e.g. il2cpp.exe) inside a development/source checkout of the IL2CPP folder. The code searches <il2CppFolder>/<toolName>/bin recursively for an executable matching the expected name; if zero candidates are found it assumes the tool was never built there.

Source

Thrown at Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:589

            if (isDevelopmentLocation)
            {
                // Locating the correct development build to use is a little tricky.  Complications come from
                // 1) We don't know if the Debug or Release build is desired.  To overcome this we will pick whichever was modified most recently
                // 2) We don't know if the published or non-published build is desired.  Again, we'll use whichever was modified most recently
                // 3) Published builds for all platforms may or may not be built.  We need to make sure not to pick a build for a different platform

                // Note that this logic will intentionally avoid checking for an expected TFM.  This is a dev build.  Using w/e is newest is probably
                // the most robust and maintainable approach.

                var toolBinDirectory = Path.Combine(il2CppFolder, toolName, "bin").ToNPath();
#pragma warning disable UA2001 // The Banned API Analyzer produces compile errors for any new Linq code. This pre-existing usage has been suppressed, but should be rewritten if possible.
                var candidates = toolBinDirectory.Files($"*{expectedToolExecutableName}", recurse: true)
#pragma warning restore UA2001
                    .OrderByDescending(f => f.GetLastWriteTimeUtc())
                    .ToArray();

                if (candidates.Length == 0)
                    throw new InvalidOperationException($"{toolName} does not appear to be built in {il2CppFolder}");

                var expectedPublishDirectoryName = BinaryDirectoryForPlatform(platform).ToNPath();

                foreach (var candidate in candidates)
                {
                    // Examples :
                    // 1)   il2cpp/bin/Release/<tfm>/il2cpp.exe
                    // 2)   il2cpp/bin/Debug/<tfm>/il2cpp.exe
                    if (candidate.Parent.Parent.Parent.FileName == "bin")
                    {
                        // Found a non-published build
                        return candidate.ToString();
                    }

                    // Examples :
                    // 1)   il2cpp/bin/Release/<tfm>/<platform dir>/publish/il2cpp.exe
                    // 2)   il2cpp/bin/Debug/<tfm>/<platform dir>/publish/il2cpp.exe
                    if (candidate.Parent.FileName == "publish" && candidate.Parent.Parent.FileName == expectedPublishDirectoryName)

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Build the IL2CPP toolchain in the dev enlistment (e.g. run the bee/build script that produces <toolName>/bin/<config>/<tfm>/<exe>).
  2. Verify il2CppFolder resolves to the correct source root containing the tool project.
  3. If not doing dev builds, unset the dev-override env/setting so the deploy location is used instead.

Example fix

/* no source edit; environment fix */
// before: IL2CPP dev folder points at un-built checkout
// after: build il2cpp toolchain first
//   bee il2cpp::il2cpp
// then retry the editor build
Defensive patterns

Strategy: validation

Validate before calling

var binDir = Path.Combine(il2CppFolder, toolName, "bin");
if (!Directory.Exists(binDir) || !Directory.EnumerateFiles(binDir, "*" + expectedToolExecutableName, SearchOption.AllDirectories).Any())
    throw new InvalidOperationException($"Build the {toolName} toolchain in {il2CppFolder} first.");

Try / catch

try { var exe = ResolveToolExecutable(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("does not appear to be built"))
{ ReportDevBuildMissing(ex); throw; }

Prevention

When it happens

Trigger: Running from a dev IL2CPP location (isDevelopmentLocation == true) where toolName/bin does not exist or contains no file matching *<expectedToolExecutableName>; the tool project has not been compiled, or the checkout is incomplete.

Common situations: Building the editor from a source enlistment where the IL2CPP submodule hasn't been built; pointing the dev override at a stale or partial clone; renaming/moving the tool project so the bin output path changed.

Related errors


AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13). Data as JSON: /api/errors/bc2d7050f094e024. Report an issue: GitHub.