microsoft/semantic-kernel · error · InvalidOperationException
TopicId does not match the subscription.
Error message
TopicId does not match the subscription.
What it means
TypePrefixSubscription.MapToAgent checks Matches(topic) (topic.Type.StartsWith(TopicTypePrefix, Ordinal)) and throws InvalidOperationException if it does not. The XML doc explicitly states MapToAgent should only be called after Matches returns true. The runtime always calls Matches before MapToAgent, so reaching this throw indicates a logic error or direct misuse.
Source
Thrown at dotnet/src/Agents/Runtime/Core/TypePrefixSubscription.cs:72
/// </summary>
/// <param name="topic">The topic to check.</param>
/// <returns><c>true</c> if the topic's type starts with the subscription's prefix, <c>false</c> otherwise.</returns>
public bool Matches(TopicId topic)
{
return topic.Type.StartsWith(this.TopicTypePrefix, StringComparison.Ordinal);
}
/// <summary>
/// Maps a <see cref="TopicId"/> to an <see cref="AgentId"/>. Should only be called if <see cref="Matches"/> returns true.
/// </summary>
/// <param name="topic">The topic to map.</param>
/// <returns>An <see cref="AgentId"/> representing the agent that should handle the topic.</returns>
/// <exception cref="InvalidOperationException">Thrown if the topic does not match the subscription.</exception>
public AgentId MapToAgent(TopicId topic)
{
if (!this.Matches(topic))
{
throw new InvalidOperationException("TopicId does not match the subscription.");
}
return new AgentId(this.AgentType, topic.Source); // No need for .Name, since AgentType implicitly converts to string
}
/// <summary>
/// Determines whether the specified object is equal to the current subscription.
/// </summary>
/// <param name="obj">The object to compare with the current instance.</param>
/// <returns><c>true</c> if the specified object is equal to this instance; otherwise, <c>false</c>.</returns>
public override bool Equals([NotNullWhen(true)] object? obj)
{
return
obj is TypePrefixSubscription other &&
(this.Id == other.Id ||
(this.AgentType == other.AgentType &&
this.TopicTypePrefix == other.TopicTypePrefix));
}View on GitHub (pinned to c028a0c7dc)
Solutions
- Always call `if (subscription.Matches(topic))` before MapToAgent.
- Verify the TopicTypePrefix matches (is a prefix of) the topic types you publish.
- Let the runtime perform the mapping rather than calling MapToAgent manually.
Example fix
// before
var agentId = subscription.MapToAgent(topic);
// after
if (!subscription.Matches(topic)) { /* skip / log */ return; }
var agentId = subscription.MapToAgent(topic); Defensive patterns
Strategy: validation
Validate before calling
if (!subscription.Matches(topic))
{
// topic does not match this prefix subscription; skip
return;
}
AgentId target = subscription.MapToAgent(topic); Type guard
bool Handles(TypePrefixSubscription sub, TopicId t) => t.Type.StartsWith(sub.TopicTypePrefix, StringComparison.Ordinal);
Prevention
- Always call Matches() before MapToAgent().
- Let the runtime perform mapping rather than calling MapToAgent manually.
- Ensure TopicTypePrefix is a true prefix of the topic types you publish.
When it happens
Trigger: Calling subscription.MapToAgent(topic) directly without first confirming Matches(topic); a topic whose Type does not start with the configured TopicTypePrefix; concurrent mutation of the topic between the Matches and MapToAgent calls.
Common situations: Custom subscription orchestration code that skips the Matches check; a misconfigured prefix that does not correspond to the topics being published; race where topic is rebuilt between calls.
Related errors
- TopicId does not match the subscription.
- Subscription with id {subscription.Id} already exists.
- Subscription with id {subscriptionId} does not exist.
- Invalid AgentId key: '{key}'. Must only contain ASCII charac
- Invalid AgentId type: '{type}'. Must be alphanumeric (a-z, 0
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/d6b019267f607f2a.
Report an issue: GitHub.