From agents-for-dotnet
Use when troubleshooting an agent built with the Microsoft Agents SDK (Microsoft.Agents.Hosting.AspNetCore and related packages) in C# / .NET. Trigger on any of these symptoms: build or C# compile errors, crashes on startup, 401 or auth errors on incoming requests, the bot not responding to messages, appsettings.json configuration problems, Azure AD credential failures (AADSTS errors), port conflicts, or the agent not connecting in Teams or the Agents Playground. Use even if the user doesn't mention the SDK by name — trigger on symptoms like "my bot won't start", "getting 401s", or "bot isn't responding."
How this skill is triggered — by the user, by Claude, or both
Slash command
/agents-for-dotnet:agents-sdk-dotnet-debuggingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Most agent failures fall into one of three categories: the code doesn't build or start, the configuration is wrong, or the agent isn't reachable. Work through this checklist in order — each step confirms a prerequisite for the next.
Most agent failures fall into one of three categories: the code doesn't build or start, the configuration is wrong, or the agent isn't reachable. Work through this checklist in order — each step confirms a prerequisite for the next.
You MUST create a task for each of these items and complete them in order:
appsettings.json configuration.dotnet build
Expected: exits with code 0, no errors. Fix any C# compile errors before continuing.
Common build errors:
dotnet add package Microsoft.Agents.Hosting.AspNetCoreusing statement; see the agents-sdk-dotnet skill for correct namespaces<TargetFramework> in .csprojRun with detailed logging:
dotnet run
Or with verbose logging:
dotnet run --verbosity detailed
To enable debug-level SDK logging, add to appsettings.Development.json:
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"Microsoft.Agents": "Debug",
"Microsoft.AspNetCore": "Warning"
}
}
}
Watch for crash output. Common startup errors:
Unable to resolve service for type 'IStorage' — missing builder.Services.AddSingleton<IStorage, MemoryStorage>() in Program.csAddAgentAspNetAuthentication missing — add builder.Services.AddAgentAspNetAuthentication(builder.Configuration)netstat -ano | findstr :3978 (Windows) or lsof -i :3978 (macOS/Linux)InvalidOperationException on startup — check appsettings.json structure, especially Connections and ConnectionsMapIf the agent starts cleanly, you should see output like:
Now listening on: http://localhost:3978
curl -s -o /dev/null -w "%{http_code}" \
-X POST http://localhost:3978/api/messages \
-H "Content-Type: application/json" \
-d '{}'
| Response | Meaning |
|---|---|
401 | Agent is running, auth is active — this is correct for a configured agent |
200 | Agent is running with auth disabled (TokenValidation:Enabled = false) — correct for local dev |
000 or connection refused | Agent is not running, wrong port, or crashed on startup |
appsettings.json configurationConfiguration mistakes are the most common source of failures. Check each area below.
ASP.NET Core auto-loads appsettings.json and appsettings.{Environment}.json. Check that:
"Copy to Output Directory": "PreserveNewest" in .csproj or is at the content rootASPNETCORE_ENVIRONMENT is set correctly (Development for local dev)The SDK requires a specific JSON structure. Common mistakes:
// WRONG — flat format (this is Node.js env var style, not appsettings)
{
"ClientId": "...",
"ClientSecret": "...",
"TenantId": "..."
}
// CORRECT
{
"Connections": {
"ServiceConnection": {
"Settings": {
"AuthType": "ClientSecret",
"AuthorityEndpoint": "https://login.microsoftonline.com/<tenantId>",
"ClientId": "<appId>",
"ClientSecret": "<secret>",
"Scopes": ["https://api.botframework.com/.default"]
}
}
}
}
If ConnectionsMap is present, it must be a JSON array with proper structure:
// WRONG — object instead of array
"ConnectionsMap": {
"ServiceUrl": "*",
"Connection": "ServiceConnection"
}
// CORRECT — array
"ConnectionsMap": [
{
"ServiceUrl": "*",
"Connection": "ServiceConnection"
}
]
If omitted, the SDK defaults to mapping * to the first connection.
{
"TokenValidation": {
"Enabled": true,
"Audiences": ["<your-app-id>"],
"TenantId": "<your-tenant-id>"
}
}
Audiences must include your ClientIdTenantId must match the tenant where the app registration livesEnabled: false for anonymous local developmentIf your agent uses user sign-in, verify the AgentApplication:UserAuthorization section:
{
"AgentApplication": {
"UserAuthorization": {
"DefaultHandlerName": "graph",
"AutoSignin": true,
"Handlers": {
"graph": {
"Settings": {
"AzureBotOAuthConnectionName": "GraphOAuthConnection",
"Title": "Sign In",
"Text": "Please sign in"
}
}
}
}
}
}
The handler key (graph) must match the autoSignInHandlers used in route registration. A mismatch causes the sign-in flow to fail silently.
Once appsettings.json looks correct, confirm the credentials actually work:
curl -s -X POST \
"https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" \
-d "grant_type=client_credentials\
&client_id=$clientId\
&client_secret=$clientSecret\
&scope=https://api.botframework.com/.default" \
| jq '{token_type, expires_in, error, error_description}'
A successful response includes access_token. Common errors:
| Error code | Cause |
|---|---|
AADSTS700016 | ClientId not found in tenant — wrong ID or wrong tenant |
AADSTS7000215 | Invalid ClientSecret — expired or incorrect |
AADSTS90002 | TenantId not found |
The Agents Playground acts as a mock connector and channel client.
Install:
npm install -g agentsplayground
Run against an anonymous agent:
Start your agent:
dotnet run
In a separate terminal:
agentsplayground -c emulator
Run against an authenticated agent:
agentsplayground -c msteams \
--client-id <your-app-id> \
--client-secret <your-secret> \
--tenant-id <your-tenant-id>
Channel options (-c): msteams, webchat, directline, emulator, agents
If the playground connects but messages don't get responses, the agent is running but a message handler may be missing. Add a fallback handler to confirm:
OnActivity(ActivityTypes.Message, async (ctx, state, ct) =>
{
await ctx.SendActivityAsync($"Echo: {ctx.Activity.Text}", cancellationToken: ct);
}, rank: RouteRank.Last);
| Error | Cause | Fix |
|---|---|---|
Unable to resolve service for type 'IStorage' | Missing storage registration | Add builder.Services.AddSingleton<IStorage, MemoryStorage>() |
MapAgentApplicationEndpoints 404 | Using MapAgentEndpoints (compat) with AgentApplication | Switch to MapAgentApplicationEndpoints |
MapAgentEndpoints 404 | Using MapAgentApplicationEndpoints with ActivityHandler | Switch to MapAgentEndpoints |
InvalidOperationException: No agent registered | Missing builder.AddAgent<T>() | Add builder.AddAgent<MyAgent>() |
| 401 on every request | TokenValidation:Enabled is true with no/wrong credentials | Set to false for local dev, or fix credentials |
System.Text.Json.JsonException on card deserialization | Wrong JSON structure in card content | Validate card JSON separately |
| OAuth sign-in card appears but token exchange fails | Wrong AzureBotOAuthConnectionName | Verify the connection name matches Azure Bot resource OAuth settings |
| Streaming chunks not appearing | Missing EndStreamAsync call | Always call await ctx.StreamingResponse.EndStreamAsync(ct) in a finally block |
OAuth connection names can only be tested end-to-end through a real sign-in flow:
Azure Portal → Your Bot Resource → Settings → OAuth Connection Settings → [your connection] → Test Connection
This confirms the connection name matches, the OAuth app has the right scopes, and the redirect URI (https://token.botframework.com/.auth/web/redirect) is registered on the app registration.
If you hit a problem this skill couldn't solve, found a workaround, or noticed something wrong or outdated, that's valuable — please help improve this skill for everyone.
Draft a suggested issue title and body based on the conversation, then ask the user to open it at: https://github.com/microsoft/agents/issues/new
A good issue includes:
npx claudepluginhub leahyra/microsoft-365-agent-sdk --plugin agents-for-netGuides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.
Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.
Synthesizes the current conversation into a structured spec (PRD) and publishes it to the project issue tracker with a ready-for-agent label, without interviewing the user.
6plugins reuse this skill
First indexed Jun 29, 2026