microsoft/semantic-kernel · error · InvalidOperationException
Agent with name {agentId.Type} not found.
Error message
Agent with name {agentId.Type} not found. What it means
The InProcessRuntime threw this because it received a message (direct send, or a publish mapped through a subscription) whose target AgentId.Type has no registered factory. EnsureAgentAsync first checks the live agentInstances cache, then looks up _agentFactories by agentId.Type; if neither matches, it throws. In short: the runtime was asked to deliver to an agent type it was never told how to build.
Source
Thrown at dotnet/src/Agents/Runtime/InProcess/InProcessRuntime.cs:423
MessageContext messageContext = new(envelope.MessageId, combinedSource.Token)
{
Sender = envelope.Sender,
IsRpc = false
};
AgentId receiver = envelope.Receiver.Value;
IHostableAgent agent = await this.EnsureAgentAsync(receiver).ConfigureAwait(false);
return await agent.OnMessageAsync(envelope.Message, messageContext).ConfigureAwait(false);
}
private async ValueTask<IHostableAgent> EnsureAgentAsync(AgentId agentId)
{
if (!this.agentInstances.TryGetValue(agentId, out IHostableAgent? agent))
{
if (!this._agentFactories.TryGetValue(agentId.Type, out Func<AgentId, IAgentRuntime, ValueTask<IHostableAgent>>? factoryFunc))
{
throw new InvalidOperationException($"Agent with name {agentId.Type} not found.");
}
agent = await factoryFunc(agentId, this).ConfigureAwait(false);
this.agentInstances.Add(agentId, agent);
}
return this.agentInstances[agentId];
}
private async Task FinishAsync(CancellationToken token)
{
foreach (IHostableAgent agent in this.agentInstances.Values)
{
if (!token.IsCancellationRequested)
{
await agent.CloseAsync().ConfigureAwait(false);
}
}View on GitHub (pinned to c028a0c7dc)
Solutions
- Register the agent factory for that exact AgentType string before any send/publish: await runtime.RegisterAgentFactoryAsync("<type>", (id, rt) => ...);
- Verify the AgentType used in AgentId and in subscriptions matches the registered type character-for-character (watch case and whitespace).
- Ensure subscriptions (AddSubscriptionAsync) map topics to agent types that are all registered; a publish will route through subscription.MapToAgent(topic) and hit EnsureAgentAsync.
- Confirm you are calling send/publish on the same InProcessRuntime instance you registered factories on.
- If loading persisted state, register every agent type referenced in the state before calling LoadStateAsync.
Example fix
// before
await runtime.SendMessageAsync(msg, new AgentId("Assistant", "a1"));
// -> InvalidOperationException: Agent with name Assistant not found.
// after - register the factory first, matching the type exactly
await runtime.RegisterAgentFactoryAsync("Assistant",
(id, rt) => ValueTask.FromResult<IHostableAgent>(new MyAgent(id, rt)));
await runtime.SendMessageAsync(msg, new AgentId("Assistant", "a1")); Defensive patterns
Strategy: validation
Validate before calling
// Before sending/publishing, confirm the target type is registered.
// (Reflection-based check because _agentFactories is private; prefer tracking
// registered types yourself in a set as you call RegisterAgentFactoryAsync.)
HashSet<string> registeredTypes = new();
async ValueTask Register(string type, Func<AgentId, IAgentRuntime, ValueTask<IHostableAgent>> factory)
{
await runtime.RegisterAgentFactoryAsync(type, factory);
registeredTypes.Add(type);
}
async Task SendSafe(object msg, AgentId recipient)
{
if (!registeredTypes.Contains(recipient.Type))
throw new InvalidOperationException($"Refusing to send: agent type '{recipient.Type}' is not registered.");
await runtime.SendMessageAsync(msg, recipient);
} Try / catch
try
{
await runtime.SendMessageAsync(msg, recipient);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("not found"))
{
// agent type not registered; log recipient.Type and register or fail gracefully
logger.LogWarning("Agent type {Type} not registered: {Msg}", recipient.Type, ex.Message);
} Prevention
- Register every agent factory before calling StartAsync or any send/publish.
- Keep a single source of truth for AgentType string constants to avoid typos and casing mismatches.
- Register all agent types referenced by subscriptions and by any persisted state you load.
- Use the same runtime instance for registration and for messaging.
When it happens
Trigger: Calling runtime.SendMessageAsync(message, new AgentId("SomeType", key)) before RegisterAgentFactoryAsync("SomeType", ...). Or PublishMessageAsync to a TopicId whose TypePrefixSubscription/Subscription maps to an AgentType that was never registered. Also GetAgentMetadataAsync, SaveAgentStateAsync, LoadAgentStateAsync, and GetAgentAsync(lazy:false) on an unregistered AgentId.
Common situations: Typo or casing mismatch between the string used at RegisterAgentFactoryAsync and the AgentType at send time (the dictionary key is an exact match, case-sensitive). Registering the agent on one runtime instance but sending on another. Forgetting to await RegisterAgentFactoryAsync before publishing. Restoring state (LoadStateAsync) that references agent types no longer registered.
Related errors
- Configuration not found, please setup the notebooks first us
- AZURE_OPENAI_ENDPOINT is not set.
- AZURE_OPENAI_ENDPOINT is not set.
- AZURE_OPENAI_ENDPOINT is not set.
- AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/8f3605f0a47129f6.
Report an issue: GitHub.