Skip to content

Fix Connect-GitHubApp AddRange failure when a single installation exists #567

@MariusStorhaug

Description

Context

Connect-GitHubApp is called without parameters to connect to all available installations of a GitHub App.
This is the standard usage in automation workflows such as the PSModule/Distributor
sync workflow, which calls Connect-GitHubApp to create installation access token contexts before processing repositories.

Request

When a GitHub App has only one installation, Connect-GitHubApp fails with the following error:

Cannot convert argument "c", with value: "GitHubAppInstallation", for "AddRange" to type
"System.Collections.ICollection": "Cannot convert the "GitHubAppInstallation" value of type
"GitHubAppInstallation" to type "System.Collections.ICollection"."

The error occurs in the default parameter set branch of Connect-GitHubApp, which handles the "connect to all
installations" case. The workflow exits with code 1 and no installations are connected.

This has caused two consecutive daily failures of the Distributor sync workflow
(March 27 and March 28, 2026), both running GitHub module version 0.42.0.

What is expected

Connect-GitHubApp should connect to all available installations regardless of whether one or many exist.
A single installation should be handled identically to multiple installations.

Acceptance criteria

  • Connect-GitHubApp succeeds when the app has exactly one installation
  • Connect-GitHubApp continues to work correctly when the app has multiple installations
  • Connect-GitHubApp handles zero installations gracefully (no error, just no connections made)

Technical decisions

Root cause: In the default branch of the switch statement in Connect-GitHubApp, the code calls:

$selectedInstallations.AddRange((Get-GitHubAppInstallation -Context $Context))

ArrayList.AddRange() requires an
ICollection argument. When Get-GitHubAppInstallation returns a single GitHubAppInstallation object, PowerShell
does not wrap it in an array — it passes the bare object. A single object does not implement ICollection, so the call
throws. When multiple installations exist, PowerShell returns an [object[]] array, which does implement ICollection,
so the call succeeds.

This is a well-known PowerShell pipeline unrolling behavior:
a command returning one item yields the item itself, not a one-element array.

Fix approach: Wrap the result in the array sub-expression operator @()
to guarantee an array is always passed:

$selectedInstallations.AddRange(@(Get-GitHubAppInstallation -Context $Context))

Alternatively, switch to the same pattern used in the Filtered branch — iterate and .Add() each item individually:

Get-GitHubAppInstallation -Context $Context | ForEach-Object {
    $null = $selectedInstallations.Add($_)
}

Preferred approach: Use @() wrapping. It is a one-character fix, consistent with standard PowerShell idiom, and
preserves the existing code structure. The Filtered branch already handles this correctly by using individual .Add()
calls via ForEach-Object.

File: src/functions/public/Auth/Connect-GitHubApp.ps1, line 156 (the default case in the switch block).

Breaking changes: None. This is a bug fix — the current behavior is a crash, not a feature.

Test approach: Add a test that calls Connect-GitHubApp when only one installation exists and verify it does not throw.


Implementation plan

Core fix

  • Update Connect-GitHubApp.ps1 line 156: wrap Get-GitHubAppInstallation result with @() in the default branch

Tests

  • Add or update test for Connect-GitHubApp with a single installation scenario
  • Verify existing tests still pass for multi-installation scenarios

Downstream validation

Metadata

Metadata

Labels

bugSomething isn't workingpatch

Type

No type

Projects

Status

Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions