microsoft/autogen · error · ValueError

Invalid topic id: {topic_id}

Error message

Invalid topic id: {topic_id}

What it means

TopicId.from_str() parses strings of the exact form 'type/source' (maxsplit=1, so the source may itself contain slashes). If the string has no '/' at all, split yields one item and from_str raises ValueError with the offending string. This is the inverse of TopicId.__str__, so any string that did not come from str(TopicId) is suspect.

Source

Thrown at python/packages/autogen-core/src/autogen_core/_topic.py:45

    source: str
    """Identifies the context in which an event happened. Adhere's to the cloud event spec.

    Learn more here: https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md#source-1
    """

    def __post_init__(self) -> None:
        if is_valid_topic_type(self.type) is False:
            raise ValueError(f"Invalid topic type: {self.type}. Must match the pattern: ^[\\w\\-\\.\\:\\=]+\\Z")

    def __str__(self) -> str:
        return f"{self.type}/{self.source}"

    @classmethod
    def from_str(cls, topic_id: str) -> Self:
        """Convert a string of the format ``type/source`` into a TopicId"""
        items = topic_id.split("/", maxsplit=1)
        if len(items) != 2:
            raise ValueError(f"Invalid topic id: {topic_id}")
        type, source = items[0], items[1]
        return cls(type, source)

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Provide the string in 'type/source' form: `TopicId.from_str("orders/created")`.
  2. If you only have a type, construct directly: `TopicId("orders", source)` with an explicit source.
  3. Validate input with `'/' in value` before calling from_str and fail with a clear config error.

Example fix

# before
topic = TopicId.from_str("orders.created")  # ValueError: Invalid topic id

# after
topic = TopicId.from_str("orders.created/order-service")  # type='orders.created', source='order-service'
Defensive patterns

Strategy: validation

Validate before calling

def parse_topic_id(s: str) -> TopicId:
    if "/" not in s:
        raise ValueError(f"expected 'type/source', got {s!r}")
    return TopicId.from_str(s)

Type guard

def looks_like_topic_id_str(s: str) -> bool:
    return isinstance(s, str) and "/" in s

Try / catch

try:
    topic = TopicId.from_str(raw)
except ValueError:
    topic = TopicId(raw, default_source)  # treat the raw value as a bare type

Prevention

When it happens

Trigger: `TopicId.from_str("my_topic")` (no slash), `TopicId.from_str("")`, or parsing a config/env value that holds a bare topic type instead of a full topic id. Note 'a/b/c' is valid — source becomes 'b/c'.

Common situations: Config files storing just the topic type where the code expects type/source; joining values with a different delimiter ('.' or ':') and parsing with from_str; hand-written topic strings in tests or CLI args.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/8b74472b51bbaba4. Report an issue: GitHub.