{"record":{"id":"47facc2bd2ab16cb","repo":"microsoft/semantic-kernel","slug":"request-failed-nameof-getuserprofileasync","errorCode":null,"errorMessage":"Request failed: {nameof(GetUserProfileAsync)}","messagePattern":"Request failed: (.+?)","errorType":"exception","errorClass":"InvalidDataException","httpStatus":null,"severity":"error","filePath":"dotnet/samples/LearnResources/Plugins/GitHub/GitHubPlugin.cs","lineNumber":23,"sourceCode":"using Microsoft.SemanticKernel;\n\nnamespace Plugins;\n\ninternal sealed class GitHubSettings\n{\n    public string BaseUrl { get; set; } = \"https://api.github.com\";\n\n    public string Token { get; set; } = string.Empty;\n}\n\ninternal sealed class GitHubPlugin(GitHubSettings settings)\n{\n    [KernelFunction]\n    public async Task<GitHubModels.User> GetUserProfileAsync()\n    {\n        using HttpClient client = this.CreateClient();\n        JsonDocument response = await MakeRequestAsync(client, \"/user\");\n        return response.Deserialize<GitHubModels.User>() ?? throw new InvalidDataException($\"Request failed: {nameof(GetUserProfileAsync)}\");\n    }\n\n    [KernelFunction]\n    public async Task<GitHubModels.Repo> GetRepositoryAsync(string organization, string repo)\n    {\n        using HttpClient client = this.CreateClient();\n        JsonDocument response = await MakeRequestAsync(client, $\"/repos/{organization}/{repo}\");\n\n        return response.Deserialize<GitHubModels.Repo>() ?? throw new InvalidDataException($\"Request failed: {nameof(GetRepositoryAsync)}\");\n    }\n\n    [KernelFunction]\n    public async Task<GitHubModels.Issue[]> GetIssuesAsync(\n        string organization,\n        string repo,\n        [Description(\"default count is 30\")]\n        int? maxResults = null,\n        [Description(\"open, closed, or all\")]","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/samples/LearnResources/Plugins/GitHub/GitHubPlugin.cs#L5-L41","documentation":"An InvalidDataException thrown by GitHubPlugin.GetUserProfileAsync when JsonDocument.Deserialize<GitHubModels.User>() returns null. Because the GitHub /user response is a JSON object, a null result means the deserialization target mapping yielded null (empty/malformed body or incompatible shape), not a normal API error.","triggerScenarios":"Calling GetUserProfileAsync when the /user endpoint returns a body that deserializes to a null User object (empty body, unexpected JSON token, schema mismatch).","commonSituations":"Missing/invalid GitHub token causing a non-JSON error response; API schema change; network proxy returning an HTML error page; rate-limit body that does not map to User.","solutions":["Check MakeRequestAsync throws on non-2xx and that the token (GitHubSettings.Token) is valid.","Log the raw response body to see what was actually returned before deserialization.","Confirm GitHubModels.User matches the current GitHub API schema.","Handle null by returning a clearer error including status code and body."],"exampleFix":"// before\nreturn response.Deserialize<GitHubModels.User>() ?? throw new InvalidDataException($\"Request failed: {nameof(GetUserProfileAsync)}\");\n// after - include status/body context\nvar user = response.Deserialize<GitHubModels.User>();\nif (user is null) throw new InvalidDataException($\"{nameof(GetUserProfileAsync)} returned non-deserializable body: {response.RootElement}\");\nreturn user;","handlingStrategy":"try-catch","validationCode":"if (string.IsNullOrWhiteSpace(settings.Token)) throw new InvalidOperationException(\"GitHub token is not configured.\");\nif (!Uri.IsWellFormedUriString(settings.BaseUrl, UriKind.Absolute)) throw new InvalidOperationException(\"Invalid BaseUrl.\");","typeGuard":null,"tryCatchPattern":"try { return await plugin.GetUserProfileAsync(); }\ncatch (InvalidDataException ex) when (ex.Message.Contains(nameof(GitHubPlugin.GetUserProfileAsync))) { /* log raw body, verify token/scopes, surface to caller */ }","preventionTips":["Always set a valid GitHub token with required scopes.","Make the HTTP layer throw on non-2xx so error bodies never reach the deserializer.","Log the raw response body when deserialization yields null."],"tags":["github","plugin","deserialization","network"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}