{"record":{"id":"be16cbf70a590deb","repo":"microsoft/semantic-kernel","slug":"invalid-topic-id-topic-id","errorCode":null,"errorMessage":"Invalid topic id: {topic_id}","messagePattern":"Invalid topic id: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/runtime/core/topic.py","lineNumber":56,"sourceCode":"\n    Learn more here: https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md#source-1\n    \"\"\"\n\n    def __post_init__(self) -> None:\n        \"\"\"Validate the topic type and source.\"\"\"\n        if is_valid_topic_type(self.type) is False:\n            raise ValueError(f\"Invalid topic type: {self.type}. Must match the pattern: ^[\\\\w\\\\-\\\\.\\\\:\\\\=]+\\\\Z\")\n\n    def __str__(self) -> str:\n        \"\"\"Convert the TopicId to a string.\"\"\"\n        return f\"{self.type}/{self.source}\"\n\n    @classmethod\n    def from_str(cls, topic_id: str) -> Self:\n        \"\"\"Convert a string of the format ``type/source`` into a TopicId.\"\"\"\n        items = topic_id.split(\"/\", maxsplit=1)\n        if len(items) != 2:\n            raise ValueError(f\"Invalid topic id: {topic_id}\")\n        type, source = items[0], items[1]\n        return cls(type, source)\n","sourceCodeStart":38,"sourceCodeEnd":59,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/runtime/core/topic.py#L38-L59","documentation":"Raised by TopicId.from_str when the input does not split into exactly two parts on the first '/'. from_str expects the format type/source; a string with no '/' yields a single part and raises ValueError. (A string like '/source' yields an empty type, which then fails the regex check and raises the invalid-type error instead.)","triggerScenarios":"Calling TopicId.from_str('novalue') with no slash; calling from_str('') on an empty string; any input missing the type/source separator.","commonSituations":"Parsing user input or configuration that lacks the type/source format; constructing the string with an off-by-one; passing a bare topic name.","solutions":["Ensure the string is in 'type/source' format with at least one '/'.","Validate the presence of '/' (and a non-empty type) before calling from_str.","If you already have the parts, build TopicId directly via TopicId(type, source)."],"exampleFix":"// before\ntopic = TopicId.from_str('mytopic')  # no '/' -> ValueError\n\n// after\ntopic = TopicId.from_str('mytopic/source-1')\n# or, when you already have the parts:\ntopic = TopicId(type='mytopic', source='source-1')","handlingStrategy":"validation","validationCode":"def is_valid_topic_id_str(s: str) -> bool:\n    parts = s.split('/', maxsplit=1)\n    return len(parts) == 2 and bool(parts[0]) and bool(parts[1])","typeGuard":"def looks_like_topic_id_str(s: str) -> bool:\n    parts = s.split('/', maxsplit=1)\n    return len(parts) == 2 and bool(parts[0])","tryCatchPattern":null,"preventionTips":["Ensure 'type/source' format with a non-empty type before calling from_str.","Prefer constructing TopicId(type, source) directly when you have the parts.","Validate user/config input at the boundary before parsing."],"tags":["topic","parsing","validation"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}