microsoft/semantic-kernel · error · InvalidDataException

Request failed: {nameof(GetIssuesAsync)}

Error message

Request failed: {nameof(GetIssuesAsync)}

What it means

An InvalidDataException thrown by GetIssuesAsync when the /repos/{org}/{repo}/issues response deserializes to a null Issue[] (or non-array body). The issues endpoint returns a JSON array; a null result means the body was not a deserializable array of issues.

Source

Thrown at dotnet/samples/LearnResources/Plugins/GitHub/GitHubPlugin.cs:56

        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);
        path = BuildQuery(path, "labels", label);
        path = BuildQuery(path, "per_page", maxResults?.ToString() ?? string.Empty);

        JsonDocument response = await MakeRequestAsync(client, path);

        return response.Deserialize<GitHubModels.Issue[]>() ?? throw new InvalidDataException($"Request failed: {nameof(GetIssuesAsync)}");
    }

    [KernelFunction]
    public async Task<GitHubModels.IssueDetail> GetIssueDetailAsync(string organization, string repo, int issueId)
    {
        using HttpClient client = this.CreateClient();

        string path = $"/repos/{organization}/{repo}/issues/{issueId}";

        JsonDocument response = await MakeRequestAsync(client, path);

        return response.Deserialize<GitHubModels.IssueDetail>() ?? throw new InvalidDataException($"Request failed: {nameof(GetIssueDetailAsync)}");
    }

    private HttpClient CreateClient()
    {
        HttpClient client = new()
        {

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Confirm org/repo and that the token can read issues.
  2. Validate state/label/assignee parameters are within accepted values (open/closed/all).
  3. Inspect the raw response to ensure it is a JSON array before array deserialization.
  4. Make MakeRequestAsync throw on non-2xx so error bodies never reach the deserializer.

Example fix

// before
return response.Deserialize<GitHubModels.Issue[]>() ?? throw new InvalidDataException($"Request failed: {nameof(GetIssuesAsync)}");
// after
var issues = response.Deserialize<GitHubModels.Issue[]>();
if (issues is null) throw new InvalidDataException($"{nameof(GetIssuesAsync)}: expected issue array for {organization}/{repo}, got: {response.RootElement.GetRawText()}");
return issues;
Defensive patterns

Strategy: validation

Validate before calling

var allowed = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "", "open", "closed", "all" };
if (!allowed.Contains(state)) throw new ArgumentOutOfRangeException(nameof(state));
if (string.IsNullOrWhiteSpace(organization) || string.IsNullOrWhiteSpace(repo)) throw new ArgumentException("org/repo required");

Type guard

bool IsValidIssueState(string s) => s is "" or "open" or "closed" or "all";

Try / catch

try { return await plugin.GetIssuesAsync(org, repo, maxResults, state, label, assignee); }
catch (InvalidDataException ex) when (ex.Message.Contains(nameof(GitHubPlugin.GetIssuesAsync))) { /* verify params, token, and that body is a JSON array */ }

Prevention

When it happens

Trigger: Calling GetIssuesAsync when the issues endpoint returns a body that does not deserialize into GitHubModels.Issue[] (error object instead of array, empty, or schema mismatch).

Common situations: Bad org/repo or no access producing a JSON error object (not an array); invalid state/label/assignee query params; token scopes insufficient; API schema change.

Related errors


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