microsoft/aspire · error · InvalidOperationException
Handle ' ' not found in registry
Error message
Handle '{handleId}' not found in registry What it means
HandleRegistry.GetObject looks up the object stored for an ATS handle ID and throws this InvalidOperationException when the ID has no entry in the registry. It signals the caller passed a handle that was never registered or was removed/disposed.
Solutions
- Re-register the object (or re-request the handle from the remote host) before calling GetObject.
- Verify the handle ID is passed unmodified from where Register returned it.
- Use TryGetObject or Handles/ContainsHandle-style existence check first if available.
- If handles cross process lifetimes, re-acquire handles after each remote host restart instead of persisting them.
Example fix
// before
var obj = registry.GetObject(handleId); // throws if stale
// after
if (!registry.ContainsHandle(handleId))
{
handleId = ReRegisterObject(remoteHost);
}
var obj = registry.GetObject(handleId); Defensive patterns
Strategy: validation
Validate before calling
if (registry is null || string.IsNullOrWhiteSpace(handleId))
throw new ArgumentException("Handle ID must be non-empty before lookup.");
// pre-check (registry exposes handle enumeration/contains semantics)
if (!registry.Handles.Any(h => h.Id == handleId))
throw new InvalidOperationException($"Handle '{handleId}' is stale; re-register the object."); Type guard
bool TryGetRegistered(Aspire.Hosting.RemoteHost.Ats.HandleRegistry registry, string id, out object? obj)
{
obj = null;
if (!registry.Handles.Any(h => h.Id == id)) return false;
try { obj = registry.GetObject(id); return true; }
catch (InvalidOperationException) { return false; }
} Try / catch
try
{
var obj = registry.GetObject(handleId);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("not found in registry"))
{
handleId = ReRegisterAndAcquireHandle(remoteHost);
var obj = registry.GetObject(handleId);
} Prevention
- Treat handle IDs as process-local; never persist them across remote-host restarts.
- Re-acquire handles after any restart or reconnection.
- Pass IDs opaquely — never parse, truncate, or reformat them.
- Check registry membership before lookups in long-lived clients.
When it happens
Trigger: Calling GetObject(handleId) (or the typed overload, which calls it first) with an ID not present in _handles — e.g. a stale handle from a previous session or a mistyped ID string.
Common situations: Client cached a handle across a remote-host restart (registry is per-process); handle was unregistered/disposed earlier; ID string truncated or altered in transit.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Handle ' ' contains , expected
- Container app context not found for resource
- Could not invoke ' ' because parameter ' ' expects , but…
- ex.Message (rethrown wrapped as InvalidOperationException…
- no input with name ' ' was found
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/46da68e98c919deb.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.RemoteHost/Ats/HandleRegistry.cs:81
return true;
}
obj = null;
typeId = null;
return false;
}
/// <summary>
/// Gets the underlying object for a handle.
/// </summary>
/// <param name="handleId">The handle ID.</param>
/// <returns>The underlying object.</returns>
/// <exception cref="InvalidOperationException">Thrown if the handle is not found.</exception>
public object GetObject(string handleId)
{
if (!_handles.TryGetValue(handleId, out var entry))
{
throw new InvalidOperationException($"Handle '{handleId}' not found in registry");
}
return entry.Object;
}
/// <summary>
/// Gets the underlying object for a handle, cast to the specified type.
/// </summary>
/// <typeparam name="T">The expected type.</typeparam>
/// <param name="handleId">The handle ID.</param>
/// <returns>The underlying object.</returns>
/// <exception cref="InvalidOperationException">Thrown if the handle is not found or type doesn't match.</exception>
public T GetObject<T>(string handleId) where T : class
{
var obj = GetObject(handleId);
if (obj is not T typed)
{
throw new InvalidOperationException(
$"Handle '{handleId}' contains {obj.GetType().FullName}, expected {typeof(T).FullName}");View on GitHub (pinned to 25830f84bd)