clockworklabs/SpacetimeDB · error · InvalidOperationException
SpacetimeDBNetworkManager is a singleton and should only be
Error message
SpacetimeDBNetworkManager is a singleton and should only be attached once.
What it means
Unity-only MonoBehaviour that ticks all active SpacetimeDB connections. Awake guards a static _instance so exactly one manager exists (its Update/OnDestroy iterate a global connection list). A second instance throws InvalidOperationException from Awake, which in Unity also disables that component. ResetStaticFields clears the static on play-mode start to survive disabled domain reloading.
Source
Thrown at sdks/csharp/src/SpacetimeDBNetworkManager.cs:36
/// AutoStaticsCleanup and NoAutoStaticsCleanup is only supported in Unity 6+
/// </summary>
/// <remarks>
/// See the <see href="https://docs.unity3d.com/6000.5/Documentation/Manual/domain-reloading.html">Unity Domain Reloading Manual</see>
/// and the <see href="https://docs.unity3d.com/6000.5/Documentation/ScriptReference/RuntimeInitializeOnLoadMethodAttribute.html">RuntimeInitializeOnLoadMethodAttribute API Docs</see> for details.
/// </remarks>
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void ResetStaticFields()
{
_instance = null;
}
public void Awake()
{
// Ensure that users don't create several SpacetimeDBNetworkManager instances.
// We're using a global (static) list of active connections and we don't want several instances to walk over it several times.
if (_instance != null)
{
throw new InvalidOperationException("SpacetimeDBNetworkManager is a singleton and should only be attached once.");
}
else
{
_instance = this;
}
}
private readonly List<IDbConnection> activeConnections = new();
public bool AddConnection(IDbConnection conn)
{
if (activeConnections.Contains(conn))
{
return false;
}
activeConnections.Add(conn);
return true;
View on GitHub (pinned to 524b4487d9)
Solutions
- Search all loaded scenes for SpacetimeDBNetworkManager and keep exactly one
- Bootstrap the manager once in an init scene before additive scenes load
- When creating it programmatically, guard with FindObjectOfType<SpacetimeDBNetworkManager>() before AddComponent
Example fix
// before
gameObject.AddComponent<SpacetimeDBNetworkManager>(); // throws if one already exists
// after
if (FindObjectOfType<SpacetimeDBNetworkManager>() == null)
gameObject.AddComponent<SpacetimeDBNetworkManager>(); Defensive patterns
Strategy: validation
Validate before calling
if (FindObjectOfType<SpacetimeDBNetworkManager>() != null)
return; // singleton already present in a loaded scene
gameObject.AddComponent<SpacetimeDBNetworkManager>(); Type guard
static bool ManagerExists() => FindObjectOfType<SpacetimeDBNetworkManager>() != null;
Try / catch
try { gameObject.AddComponent<SpacetimeDBNetworkManager>(); }
catch (InvalidOperationException) { /* duplicate instance: destroy this GameObject and reuse the existing manager */ } Prevention
- Put the manager in exactly one bootstrap scene
- Before additive scene loads, assert only one instance exists
- When instantiating prefabs that carry it, strip or check the component first
When it happens
Trigger: The manager GameObject exists in two simultaneously loaded scenes (additive scene loading), a prefab with the component instantiated alongside a scene copy, or a DontDestroyOnLoad instance plus a duplicate in a reloaded scene.
Common situations: Adding SpacetimeDBNetworkManager to both the bootstrap scene and gameplay scenes 'to be safe'; duplicating a prefab that carries it; multi-scene Unity setups.
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/364d7604bd83b9da.
Report an issue: GitHub.