{"record":{"id":"f7ef4ba3d24e4499","repo":"microsoft/semantic-kernel","slug":"copilot-studio-did-not-return-a-conversation-id","errorCode":null,"errorMessage":"Copilot Studio did not return a conversation ID.","messagePattern":"Copilot Studio did not return a conversation ID\\.","errorType":"exception","errorClass":"AgentThreadOperationException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/agents/copilot_studio/copilot_studio_agent.py","lineNumber":624,"sourceCode":"                        if on_intermediate_message:\n                            await on_intermediate_message(\n                                ChatMessageContent(role=AuthorRole.ASSISTANT, name=self.name, content=action.text)\n                            )\n                yield ChatMessageContent(role=AuthorRole.ASSISTANT, name=self.name, content=activity.text)\n\n    async def _ensure_conversation(self, thread: CopilotStudioAgentThread) -> None:\n        \"\"\"Guarantee that `thread.conversation_id` is populated.\"\"\"\n        if thread.id:\n            return\n\n        async for act in self.client.start_conversation():\n            conversation_id = getattr(getattr(act, \"conversation\", None), \"id\", None)\n            if conversation_id:\n                thread.conversation_id = conversation_id\n                return\n\n        # If we reach this point, the service misbehaved, so throw\n        raise AgentThreadOperationException(\"Copilot Studio did not return a conversation ID.\")\n\n    @staticmethod\n    def _normalize_messages(messages: str | ChatMessageContent | list[str | ChatMessageContent] | None) -> list[str]:\n        \"\"\"Return a flat list[str] irrespective of the caller-supplied type.\"\"\"\n        if messages is None:\n            return []\n\n        if isinstance(messages, (str, ChatMessageContent)):\n            messages = [messages]\n\n        normalized: list[str] = []\n        for m in messages:\n            normalized.append(m.content if isinstance(m, ChatMessageContent) else str(m))\n        return normalized\n\n    @staticmethod\n    def _to_streaming(\n        msg: ChatMessageContent,","sourceCodeStart":606,"sourceCodeEnd":642,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/agents/copilot_studio/copilot_studio_agent.py#L606-L642","documentation":"Raised by CopilotStudioAgent._ensure_conversation() when iterating self.client.start_conversation() yields no activity whose .conversation.id is set. The method is called from _inner_invoke before ask_question to guarantee a conversation ID exists. Reaching the throw means the Copilot Studio service returned no usable conversation activity — a service-side misbehavior or connectivity issue. It is an AgentThreadOperationException.","triggerScenarios":"During the first invocation on a fresh thread (no conversation_id yet), _ensure_conversation calls client.start_conversation(). If the async generator produces zero activities or none carry a conversation.id, the exception fires.","commonSituations":"Copilot Studio service outage or degradation; network proxy/firewall stripping response payloads; invalid or expired access token causing the service to return error activities without a conversation; agent_identifier / environment_id pointing to a non-existent or unpublished copilot.","solutions":["Retry the invocation after a short delay — this is often a transient service issue.","Verify the agent_identifier and environment_id in settings match a published, accessible Copilot Studio agent.","Check that the access token is valid and not expired (see error 800 for auth troubleshooting).","Inspect network/proxy configuration for anything modifying or blocking the streaming response from the Power Platform endpoint.","Enable debug logging on the microsoft_agents.copilotstudio namespace to inspect the raw activities returned."],"exampleFix":"# before — single attempt, fails on transient service blip\nasync for resp in agent.invoke(\"hello\", thread=thread):\n    ...\n\n# after — retry wrapper for the first invocation\nimport asyncio\nfor attempt in range(3):\n    try:\n        async for resp in agent.invoke(\"hello\", thread=thread):\n            ...\n        break\n    except AgentThreadOperationException:\n        thread = CopilotStudioAgentThread(agent.client)  # fresh thread\n        await asyncio.sleep(2 ** attempt)","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"from semantic_kernel.exceptions.agent_exceptions import AgentThreadOperationException\nimport asyncio\n\nfor attempt in range(3):\n    thread = CopilotStudioAgentThread(agent.client)\n    try:\n        async for resp in agent.invoke(\"hello\", thread=thread):\n            process(resp)\n        break\n    except AgentThreadOperationException as exc:\n        if \"did not return a conversation ID\" not in str(exc):\n            raise\n        await asyncio.sleep(2 ** attempt)","preventionTips":["Retry the first invocation with a fresh thread — the issue is often transient.","Verify agent_identifier and environment_id point to a published copilot.","Keep the access token fresh; expired tokens can cause the service to omit conversation IDs.","Enable debug logging on microsoft_agents.copilotstudio to inspect raw activities."],"tags":["service-error","copilot-studio","conversation","transient"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}