You’ve carefully crafted your declarative agent: instructions, API plugin, knowledge sources all wired up: but when you test it, the agent cheerfully ignores everything. I’ve catalogued the four failure patterns I see most often, and once you know the playbook you can fix most issues in under five minutes.
Before You Dive In: Enable the Developer Card
The most powerful debugging tool for declarative agents is built right into Microsoft 365 Copilot: developer mode. Before you start poking at your manifest files, enable it so you can see exactly what the orchestrator is doing.
To enable developer mode, open Copilot Chat and type:
-developer on
Once enabled, every response from your agent includes a developer card with three key sections:
- Agent metadata: Identifies the agent and conversation, plus a summary of which knowledge sources were consulted.
- Capabilities: Lists each configured capability (knowledge sources, API plugins), whether it was used, and a downloadable diagnostic log.
- Actions: Shows which functions were matched to your prompt, which were selected for execution, and the full execution details including the HTTP request and response.
This card turns “something is broken” into “here is exactly what happened”. Keep developer mode on throughout your debugging sessions.
If you’re using the Microsoft 365 Agents Toolkit in VS Code, press F5 to launch your agent in a browser and use the debug panel in the toolkit. Developer mode works the same way: type -developer on in the chat to see the debug card on every response.
Failure 1: The Agent Ignores Your API
Symptom: You ask a question that should trigger an API call: say, “What’s left on my onboarding checklist?”: but instead of calling your API, the agent confidently answers from general knowledge. No API call, no real data, just a hallucinated response that sounds plausible but is completely made up.
Cause: Nine times out of ten, this is a description_for_model problem. The description in your apiPlugin.json doesn’t match how users actually phrase their questions. The orchestrator reads that description to decide when to call your API, and if the description says “Returns onboarding data” but the user asks “What do I still need to do?”: the model doesn’t make the connection.
Fix: Open your apiPlugin.json and rewrite the description to cover the full range of how users might ask about this capability. Be explicit and verbose: this isn’t a UI label, it’s a prompt for the model.
{
"description_for_model": "Use this when the user asks about their onboarding progress, task checklist, completed items, pending steps, or what they need to do next as a new employee."
}
Think of description_for_model like writing a job description. You wouldn’t write “does stuff”: you’d list every responsibility. The more scenarios you enumerate, the more reliably the orchestrator will match user questions to your API.
This single fix resolves about half of all “my agent doesn’t work” issues. Before you debug anything else, check your descriptions first.
Failure 2: 401 Unauthorized on API Calls
Symptom: This time the agent does try to call your API: progress! But the call fails with a 401 Unauthorized. In the developer card, you’ll see the action was executed but the execution details show an HTTP 401 response from your API.
Cause: Authentication misconfiguration. Either the OAuth registration ID doesn’t match, the scopes are wrong, or the API isn’t configured to accept the token that Copilot sends.
Fix: Check three things in order:
- Registration match: The
reference_idin your plugin manifest must match your OAuth registration in the Teams Developer Portal exactly. A single character off and the whole auth flow breaks. - Scopes alignment: The API scopes declared in your manifest must match what the API actually expects. If your API requires
Tasks.Readbut your manifest declaresTasks.ReadWrite, the token may not include the right permissions.
OAuth issues are the hardest to debug by staring at code alone. Open the developer card, find the failing action in the Actions section, and read the execution details: the full HTTP request and response are there. Decode the bearer token on jwt.ms to verify the audience, scopes, and claims that Copilot actually sent.
Failure 3: The Agent Calls the Wrong Tool
Symptom: You ask about a badge access issue and the agent calls getOnboardingStatus instead of createSupportTicket. It’s using one of your tools: just the wrong one.
Cause: Your tool descriptions are too similar or too vague. The model can’t distinguish which tool to invoke when the descriptions overlap. If both tools say some variation of “helps with employee issues”, the orchestrator is essentially guessing.
Fix: Make each tool description clearly distinct. Describe not just what the tool does, but when it should be used and for what kind of user question.
Instead of this:
{
"functions": [
{
"name": "getOnboardingStatus",
"description": "Helps with onboarding issues"
},
{
"name": "createSupportTicket",
"description": "Helps with employee issues"
}
]
}
Write this:
{
"functions": [
{
"name": "getOnboardingStatus",
"description": "Use this to retrieve onboarding task status, progress, and checklist items for a new employee."
},
{
"name": "createSupportTicket",
"description": "Use this to create, track, or manage IT support tickets for problems the user is experiencing, like badge issues or access requests."
}
]
}
The “why did you do that?” trick works well here. If the agent calls the wrong tool, ask it: “Why didn’t you create a support ticket?” The response often reveals exactly which description confused it: and tells you what to rewrite.
Failure 4: Works for You, Breaks for Everyone Else
Symptom: You’ve tested the agent thoroughly with your account and everything works. Your colleague tries it and gets empty responses, missing data, or errors.
Cause: Permissions. Your agent respects the security model of every source it touches: SharePoint sites, grounded content, and APIs alike. If your test account has access to a SharePoint library, an API endpoint, or a knowledge source that your colleague’s account does not, the agent will return empty results or errors for them. The agent only surfaces content and data that the requesting user has permission to access.
Fix: Verify permissions across every layer your agent touches. For knowledge sources, check that the SharePoint sites and libraries are accessible to your target audience. For API plugins, confirm that the signed-in user’s token has the required API scopes. If you’re building an HR onboarding agent for all new employees, every new employee needs the right access to every resource the agent depends on.
This is actually a feature, not a bug. The agent enforcing permissions means your company’s information boundaries stay intact. You’d never want an agent to bypass security: but you do need to make sure the right people have the right access before you roll out.
Your Debugging Superpower: The Developer Card
When something goes wrong and you’re not sure which of the four patterns you’re hitting, the developer card is your first stop. The information it surfaces maps directly to each failure pattern:
- No capabilities or actions in the card? The orchestrator didn’t engage your agent’s configured capabilities. Check your agent configuration and instructions.
- Capability listed but not executed? The knowledge source was considered but skipped. Review your instructions and grounding configuration.
- Action matched but failed execution? Download the diagnostic log from the capabilities section for details on what went wrong.
- Action executed with an empty or error response? Your API was called but returned no data. Check the execution details in the actions section for the full HTTP response, then investigate permissions.
The developer card shows you the orchestrator’s reasoning. Once you can see exactly which capabilities ran, which functions matched, and what the API returned, you stop guessing.
The Development Workflow That Saves Hours
After debugging countless agent issues, here’s the workflow I recommend:
-
Start in Copilot Chat with developer mode on: Get your instructions right first. This is the highest-leverage work, and Copilot Chat with
-developer ongives you immediate feedback on what the orchestrator is doing. Change a file, redeploy, send a message, read the developer card. No guesswork. -
Add one capability at a time: Don’t wire up knowledge, an API plugin, and an MCP server all at once. Add knowledge, test it. Add the API, test it. When something breaks, you always know what changed.
-
Test the boundaries: Don’t just test happy paths. Ask questions that should trigger guardrails. Ask ambiguous questions that could match multiple tools. Ask questions that need multiple sources. Edge cases are where agents break.
-
Use “why did you do that?” prompts: If the agent behaves unexpectedly, ask it: “Why didn’t you look up my onboarding status?” The response often reveals whether it’s a description problem, a scope problem, or an instruction conflict.
-
Always test on a real tenant: There is no substitute for a real Microsoft 365 tenant. If you don’t have one with all the required licenses and permissions, sign up for a Microsoft 365 Developer Program tenant. It gives you a fully-featured environment to test against without risking production data.
The Value of Debugging Skills
Building a declarative agent is fast: you can scaffold one in fifteen minutes. The difference between a demo and a production agent is all in the debugging. Knowing why your agent does what it does, and how to fix it when it doesn’t: that’s the skill that makes you dangerous.
Each failure pattern has a clear symptom, cause, and fix. Internalize these four and you’ll spend more time shipping agents than staring at your screen.
Resources
Have questions or want to share what you're building? Connect with me on LinkedIn or check out more on The Manifest.