Unity-Technologies/UnityCsReference · error · Exception
{nameof(UnitySourceFileUpdatersResultHandler)} can only be c
Error message
{nameof(UnitySourceFileUpdatersResultHandler)} can only be created on the main thread What it means
Thrown from the UnitySourceFileUpdatersResultHandler constructor: it must be created on the main thread because it captures the synchronization context and interacts with consent UI. Creating it on a worker thread is rejected via InternalEditorUtility.CurrentThreadIsMainThread().
Source
Thrown at Editor/Mono/Scripting/ScriptCompilation/BeeDriver/UnitySourceFileUpdatersResultHandler.cs:32
using UnityEditorInternal.APIUpdating;
using UnityEngine;
using System.Threading.Tasks;
using UnityEditorInternal;
namespace UnityEditor.Scripting.ScriptCompilation
{
class UnitySourceFileUpdatersResultHandler : SourceFileUpdatersResultHandler
{
bool m_HaveConsentToOverwriteUserScripts;
readonly UnityScriptUpdaterConsentAPI ConstentAPI;
public UnitySourceFileUpdatersResultHandler() : base(captureSynchronizationContext: true)
{
ConstentAPI = new UnityScriptUpdaterConsentAPI();
if (!InternalEditorUtility.CurrentThreadIsMainThread())
throw new Exception($"{nameof(UnitySourceFileUpdatersResultHandler)} can only be created on the main thread");
}
protected override bool ProcessUpdaterResults(SourceFileUpdaterBase.Update[] updates)
{
var problemUpdates = new List<(SourceFileUpdaterBase.Update update, Exception exception)>();
bool didUpdate = false;
void ExecuteUpdates(IEnumerable<SourceFileUpdaterBase.Update> updates)
{
foreach (var update in updates)
{
didUpdate = true;
try
{
Console.WriteLine(update.originalFileWithError);
new NPath(update.tempFileWithNewContents).Copy(update.originalFileWithError);
}
catch (Exception e)View on GitHub (pinned to 225b0fbdb5)
Solutions
- Construct the handler on the main thread (e.g. queue the creation to the main thread / EditorApplication update).
- Marshal background continuations back to the main thread before creating main-thread-only objects.
Example fix
// before
Task.Run(() => { var h = new UnitySourceFileUpdatersResultHandler(); ... });
// after
EditorApplication.delayCall += () => { var h = new UnitySourceFileUpdatersResultHandler(); ... }; Defensive patterns
Strategy: validation
Validate before calling
if (!InternalEditorUtility.CurrentThreadIsMainThread())
throw new InvalidOperationException("Construct this handler on the main thread."); Type guard
static bool IsMainThread() => InternalEditorUtility.CurrentThreadIsMainThread();
Try / catch
try { var h = new UnitySourceFileUpdatersResultHandler(); }
catch (Exception ex) when (ex.Message.Contains("main thread"))
{ /* re-run the construction via EditorApplication.delayCall / main thread dispatch */ } Prevention
- Construct main-thread-only objects from EditorApplication.delayCall or the update loop.
- Marshal Task continuations back to the main thread before touching editor APIs.
When it happens
Trigger: Instantiating UnitySourceFileUpdatersResultHandler on a non-main thread (e.g. inside a Task or thread pool callback).
Common situations: Driving the script updater from a background task/thread, or constructing the handler inside an async continuation that did not marshal back to the main thread.
Related errors
- Deployment targets main thread context can only be retrieved
- Cannot add dependency on invalid ArtifactKey.
- Must be greater than zero.
- clips
- Must not be empty.
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/d0152a3b4849b78f.
Report an issue: GitHub.