{"record":{"id":"46da68e98c919deb","repo":"microsoft/aspire","slug":"handle-handleid-not-found-in-registry","errorCode":null,"errorMessage":"Handle '{handleId}' not found in registry","messagePattern":"Handle '(.+?)' not found in registry","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.RemoteHost/Ats/HandleRegistry.cs","lineNumber":81,"sourceCode":"            return true;\n        }\n\n        obj = null;\n        typeId = null;\n        return false;\n    }\n\n    /// <summary>\n    /// Gets the underlying object for a handle.\n    /// </summary>\n    /// <param name=\"handleId\">The handle ID.</param>\n    /// <returns>The underlying object.</returns>\n    /// <exception cref=\"InvalidOperationException\">Thrown if the handle is not found.</exception>\n    public object GetObject(string handleId)\n    {\n        if (!_handles.TryGetValue(handleId, out var entry))\n        {\n            throw new InvalidOperationException($\"Handle '{handleId}' not found in registry\");\n        }\n        return entry.Object;\n    }\n\n    /// <summary>\n    /// Gets the underlying object for a handle, cast to the specified type.\n    /// </summary>\n    /// <typeparam name=\"T\">The expected type.</typeparam>\n    /// <param name=\"handleId\">The handle ID.</param>\n    /// <returns>The underlying object.</returns>\n    /// <exception cref=\"InvalidOperationException\">Thrown if the handle is not found or type doesn't match.</exception>\n    public T GetObject<T>(string handleId) where T : class\n    {\n        var obj = GetObject(handleId);\n        if (obj is not T typed)\n        {\n            throw new InvalidOperationException(\n                $\"Handle '{handleId}' contains {obj.GetType().FullName}, expected {typeof(T).FullName}\");","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.RemoteHost/Ats/HandleRegistry.cs#L63-L99","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvar obj = registry.GetObject(handleId); // throws if stale\n\n// after\nif (!registry.ContainsHandle(handleId))\n{\n    handleId = ReRegisterObject(remoteHost);\n}\nvar obj = registry.GetObject(handleId);","handlingStrategy":"validation","validationCode":"if (registry is null || string.IsNullOrWhiteSpace(handleId))\n    throw new ArgumentException(\"Handle ID must be non-empty before lookup.\");\n// pre-check (registry exposes handle enumeration/contains semantics)\nif (!registry.Handles.Any(h => h.Id == handleId))\n    throw new InvalidOperationException($\"Handle '{handleId}' is stale; re-register the object.\");","typeGuard":"bool TryGetRegistered(Aspire.Hosting.RemoteHost.Ats.HandleRegistry registry, string id, out object? obj)\n{\n    obj = null;\n    if (!registry.Handles.Any(h => h.Id == id)) return false;\n    try { obj = registry.GetObject(id); return true; }\n    catch (InvalidOperationException) { return false; }\n}","tryCatchPattern":"try\n{\n    var obj = registry.GetObject(handleId);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"not found in registry\"))\n{\n    handleId = ReRegisterAndAcquireHandle(remoteHost);\n    var obj = registry.GetObject(handleId);\n}","preventionTips":["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."],"tags":["handle-registry","remote-host","lookup"],"backgroundTag":"resource-not-found","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}