microsoft/semantic-kernel · error · InvalidDataException
Request failed: {nameof(GetRepositoryAsync)}
Error message
Request failed: {nameof(GetRepositoryAsync)} What it means
An InvalidDataException thrown by GetRepositoryAsync when the /repos/{org}/{repo} response deserializes to a null GitHubModels.Repo. Indicates the JSON shape did not map to the expected Repo object.
Source
Thrown at dotnet/samples/LearnResources/Plugins/GitHub/GitHubPlugin.cs:32
}
internal sealed class GitHubPlugin(GitHubSettings settings)
{
[KernelFunction]
public async Task<GitHubModels.User> GetUserProfileAsync()
{
using HttpClient client = this.CreateClient();
JsonDocument response = await MakeRequestAsync(client, "/user");
return response.Deserialize<GitHubModels.User>() ?? throw new InvalidDataException($"Request failed: {nameof(GetUserProfileAsync)}");
}
[KernelFunction]
public async Task<GitHubModels.Repo> GetRepositoryAsync(string organization, string repo)
{
using HttpClient client = this.CreateClient();
JsonDocument response = await MakeRequestAsync(client, $"/repos/{organization}/{repo}");
return response.Deserialize<GitHubModels.Repo>() ?? throw new InvalidDataException($"Request failed: {nameof(GetRepositoryAsync)}");
}
[KernelFunction]
public async Task<GitHubModels.Issue[]> GetIssuesAsync(
string organization,
string repo,
[Description("default count is 30")]
int? maxResults = null,
[Description("open, closed, or all")]
string state = "",
string label = "",
string assignee = "")
{
using HttpClient client = this.CreateClient();
string path = $"/repos/{organization}/{repo}/issues?";
path = BuildQuery(path, "state", state);
path = BuildQuery(path, "assignee", assignee);View on GitHub (pinned to c028a0c7dc)
Solutions
- Verify organization and repo names are correct and accessible with the configured token.
- Inspect the raw response to distinguish a 404 error body from a real Repo payload.
- Ensure MakeRequestAsync surfaces non-2xx status as exceptions rather than passing error JSON to the deserializer.
Example fix
// before
return response.Deserialize<GitHubModels.Repo>() ?? throw new InvalidDataException($"Request failed: {nameof(GetRepositoryAsync)}");
// after - guard against 404 error JSON shapes
var repo = response.Deserialize<GitHubModels.Repo>();
if (repo is null) throw new InvalidDataException($"{nameof(GetRepositoryAsync)}: '{organization}/{repo}' not found or unexpected body.");
return repo; Defensive patterns
Strategy: try-catch
Validate before calling
if (string.IsNullOrWhiteSpace(organization) || string.IsNullOrWhiteSpace(repo))
throw new ArgumentException("Organization and repo are required.");
if (string.IsNullOrWhiteSpace(settings.Token)) throw new InvalidOperationException("GitHub token is not configured."); Try / catch
try { return await plugin.GetRepositoryAsync(org, repo); }
catch (InvalidDataException ex) when (ex.Message.Contains(nameof(GitHubPlugin.GetRepositoryAsync))) { /* verify org/repo names and token access */ } Prevention
- Validate org/repo names before calling.
- Ensure the HTTP layer rejects 404 error JSON before deserialization.
- Confirm token scopes cover the target repository.
When it happens
Trigger: Calling GetRepositoryAsync(org, repo) where the repos endpoint returns a body that yields null on deserialization (404 JSON error object, empty body, schema mismatch).
Common situations: Wrong organization/repo name (GitHub returns a JSON error, not a Repo); token without repo access; API/schema drift.
Related errors
- Request failed: {nameof(GetUserProfileAsync)}
- Request failed: {nameof(GetIssuesAsync)}
- Request failed: {nameof(GetIssueDetailAsync)}
- Response is not available.
- Failed to parse response: {responseText}
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/f793378fa0e43e53.
Report an issue: GitHub.