microsoft/semantic-kernel · error · AgentInvokeException
Failed to post activity.
Error message
Failed to post activity.
What it means
An AgentInvokeException raised when posting the activity payload fails: POST {bot_endpoint}/conversations/{conversation_id}/activities returns a non-200 status. The posted activity is the user's message; if it isn't accepted the bot never receives it. Status is logged.
Source
Thrown at python/samples/demos/copilot_studio_agent/src/direct_line_agent.py:199
# Step 2: Start a conversation if one hasn't already been started.
if not self.conversation_id:
start_conv_url = f"{self.bot_endpoint}/conversations"
async with self.session.post(start_conv_url, headers=headers) as resp:
if resp.status not in (200, 201):
logger.error("Failed to start conversation. Status: %s", resp.status)
raise AgentInvokeException("Failed to start conversation.")
conv_data = await resp.json()
self.conversation_id = conv_data.get("conversationId")
if not self.conversation_id:
raise AgentInvokeException("Conversation ID not found in start response.")
# Step 3: Post the message payload.
activities_url = f"{self.bot_endpoint}/conversations/{self.conversation_id}/activities"
async with self.session.post(activities_url, json=payload, headers=headers) as resp:
if resp.status != 200:
logger.error("Failed to post activity. Status: %s", resp.status)
raise AgentInvokeException("Failed to post activity.")
_ = await resp.json() # Response from posting activity is ignored.
# Step 4: Poll for new activities using watermark until DynamicPlanFinished event is found.
finished = False
collected_data = None
watermark = None
while not finished:
url = activities_url if watermark is None else f"{activities_url}?watermark={watermark}"
async with self.session.get(url, headers=headers) as resp:
if resp.status == 200:
data = await resp.json()
watermark = data.get("watermark", watermark)
activities = data.get("activities", [])
if any(
activity.get("type") == "event" and activity.get("name") == "DynamicPlanFinished"
for activity in activities
):
collected_data = dataView on GitHub (pinned to c028a0c7dc)
Solutions
- Inspect logged status: 400 => payload; 401 => token; 404 => conversation; 429 => slow down.
- Validate the payload from _build_payload matches the activity schema the bot expects.
- Refresh the token/conversation if expired; implement backoff for 429.
Example fix
// before
if resp.status != 200:
raise AgentInvokeException("Failed to post activity.")
// after
if resp.status != 200:
body = await resp.text()
raise AgentInvokeException(f"Failed to post activity (status {resp.status}): {body}") Defensive patterns
Strategy: retry
Try / catch
try:
await post_activity(payload)
except AgentInvokeException as e:
if "Failed to post activity" in str(e):
logger.warning("Activity post failed; will retry once")
await asyncio.sleep(1); await post_activity(payload)
raise Prevention
- Validate the activity payload schema matches what the bot expects before posting.
- Handle 429 with backoff to avoid burst failures.
When it happens
Trigger: POST activities with the JSON payload returns 4xx/5xx — e.g. 400 bad payload, 401 expired token, 404 unknown conversation_id, 429 rate limited.
Common situations: Payload schema invalid for the bot; conversation_id expired/invalid; token expired; rate limiting from rapid message bursts.
Related errors
- No token received from token generation.
- Failed to generate token using bot_secret.
- No token received.
- Failed to fetch token from token endpoint.
- Exception occurred while fetching token.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/30cda30d393371c1.
Report an issue: GitHub.