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

  1. Verify organization and repo names are correct and accessible with the configured token.
  2. Inspect the raw response to distinguish a 404 error body from a real Repo payload.
  3. 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

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


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/f793378fa0e43e53. Report an issue: GitHub.