microsoft/autogen · error · InvalidOperationException

Repository owner login is null

Error message

Repository owner login is null

What it means

Thrown by the dev-team sample's GitHub webhook processor when an IssuesEvent payload has no Repository.Owner.Login (null Owner, null Login, or null Repository). The webhook handler needs org + repo + issue number to dispatch work, so it fails fast rather than processing an event it cannot attribute to a repository.

Source

Thrown at dotnet/samples/dev-team/DevTeam.Backend/Services/GithubWebHookProcessor.cs:30

using Octokit.Webhooks.Models;

namespace DevTeam.Backend.Services;

public sealed class GithubWebHookProcessor(ILogger<GithubWebHookProcessor> logger, Client client) : WebhookEventProcessor
{
    private readonly ILogger<GithubWebHookProcessor> _logger = logger;
    private readonly Client _client = client;

    protected override async Task ProcessIssuesWebhookAsync(WebhookHeaders headers, IssuesEvent issuesEvent, IssuesAction action)
    {
        try
        {
            ArgumentNullException.ThrowIfNull(headers, nameof(headers));
            ArgumentNullException.ThrowIfNull(issuesEvent, nameof(issuesEvent));
            ArgumentNullException.ThrowIfNull(action, nameof(action));

            _logger.LogInformation("Processing issue event");
            var org = issuesEvent.Repository?.Owner.Login ?? throw new InvalidOperationException("Repository owner login is null");
            var repo = issuesEvent.Repository?.Name ?? throw new InvalidOperationException("Repository name is null");
            var issueNumber = issuesEvent.Issue?.Number ?? throw new InvalidOperationException("Issue number is null");
            var input = issuesEvent.Issue?.Body ?? string.Empty;
            // Assumes the label follows the following convention: Skill.Function example: PM.Readme
            // Also, we've introduced the Parent label, that ties the sub-issue with the parent issue
            var labels = issuesEvent.Issue?.Labels
                                    .Select(l => l.Name.Split('.'))
                                    .Where(parts => parts.Length == 2)
                                    .ToDictionary(parts => parts[0], parts => parts[1]);
            if (labels == null || labels.Count == 0)
            {
                _logger.LogWarning("No labels found in issue. Skipping processing.");
                return;
            }

            long? parentNumber = labels.TryGetValue("Parent", out var value) ? long.Parse(value) : null;
            var skillName = labels.Keys.Where(k => k != "Parent").FirstOrDefault();

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Send a real captured GitHub issues webhook payload (GitHub repo Settings > Webhooks > Recent Deliverings > Redeliver) so repository.owner.login is present.
  2. If testing locally, seed the payload with a complete repository.owner.login object instead of a minimal event.
  3. Confirm the webhook is subscribed to issue events on the intended repo and the app installation has 'repository' read access.
  4. If this fires in production, log the raw payload (issuesEvent.Repository?.FullName) and check whether GitHub changed the event shape in your Octokit webhook package version.

Example fix

// before
var org = issuesEvent.Repository?.Owner.Login ?? throw new InvalidOperationException("Repository owner login is null");

// after (fail fast but log the payload shape for diagnosis)
var org = issuesEvent.Repository?.Owner?.Login
    ?? throw new InvalidOperationException($"Repository owner login is null (repo: {issuesEvent.Repository?.FullName ?? "<null>"}); webhook payload appears malformed or truncated.");
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrWhiteSpace(issuesEvent.Repository?.Owner?.Login))
{
    _logger.LogWarning("Webhook payload missing repository.owner.login; skipping event {Action}.", action);
    return; // acknowledge 200 so GitHub doesn't retry a payload we can never process
}

Type guard

static bool HasRepoContext(IssuesEvent e) => !string.IsNullOrWhiteSpace(e?.Repository?.Owner?.Login) && !string.IsNullOrWhiteSpace(e?.Repository?.Name) && e?.Issue?.Number is not null;

Try / catch

try { await ProcessIssuesWebhookAsync(headers, issuesEvent, action); } catch (InvalidOperationException ex) when (ex.Message.Contains("Repository")) { _logger.LogWarning(ex, "Malformed webhook payload; acknowledging without processing."); /* return 200 to avoid redelivery storms */ }

Prevention

When it happens

Trigger: POSTing a test/minimal issues webhook payload (e.g. from a webhook debugging tool) that omits the repository object; receiving an event for a repository the integration has limited scope on; GitHub Enterprise Cloud payloads with different serialization; replaying captured payloads through a different deserialization path.

Common situations: Testing the webhook endpoint with curl and a hand-written minimal JSON body; webhook secret validation passing but payload trimmed; Octokit webhook model version drift where Repository moved; fork-related events where owner is an organization with missing login fields.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/6edfeeedf46bc492. Report an issue: GitHub.