# How the no-mistakes GitLab Backend Handles glab Version Compatibility

> Discover how the no-mistakes GitLab backend ensures glab version compatibility by detecting unsupported flags and using alternative CLI patterns for seamless operation across all releases.

- Repository: [Kun Chen/no-mistakes](https://github.com/kunchenguid/no-mistakes)
- Tags: internals
- Published: 2026-07-19

---

**The no-mistakes GitLab backend detects unsupported flags at runtime, avoids arguments removed in newer glab releases, and falls back to alternative CLI patterns so it works across glab v1.x through current releases.**

The `internal/scm/gitlab` package in `kunchenguid/no-mistakes` implements a resilient GitLab SCM host that does not require a pinned `glab` CLI version. By using runtime feature detection and scoped command construction, the backend maintains broad **glab version compatibility** without sacrificing access to merge requests, CI checks, or pipeline data.

## Avoiding Removed Flags to Maintain glab Version Compatibility

### The `--state` Flag Omission in `FindPR`

In [`internal/scm/gitlab/gitlab.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/scm/gitlab/gitlab.go) (lines 68–71), the `FindPR` method intentionally builds the `glab mr list` command without the `--state` flag. A source comment explains that while older glab releases accepted `--state`, the flag was removed in glab v1.5x. By omitting it entirely, the backend relies on glab's default behavior of returning only open merge requests, preventing command failures on newer installations.

```go
// Example: finding a merge request without relying on the removed `--state` flag.
host := gitlab.New(cmdFactory, cliAvailable, "gitlab.example.com", "group/project")
pr, err := host.FindPR(ctx, "feature/xyz", "main")
// Internally this runs:
//   glab mr list --source-branch feature/xyz --target-branch main --output json

```

This approach is locked in place by **`TestFindPRDoesNotPassRemovedStateFlag`**, which verifies that `mr list` is never invoked with the removed flag.

## Runtime Fallbacks for glab Version Compatibility

### Unsupported `--mr` Flag Detection in `GetChecks`

The `GetChecks` method first attempts to run `glab ci status --mr <id>`, a pattern added in newer glab releases. If the command fails, the helper `isUnsupportedMRFlagError` (lines 94–115) scans `stderr` for phrases such as "unknown flag" or "unsupported flag". When a compatibility issue is detected, the backend automatically falls back to `getChecksFallback`, which reconstructs the same data using an older-compatible workflow based on `glab mr view` and `glab api`.

```go
// Example: getting CI checks, automatically falling back if `--mr` isn’t supported.
checks, err := host.GetChecks(ctx, &scm.PR{Number: "123"})
// If `glab ci status --mr 123` fails with an unknown‑flag error, the fallback
// performs:
//   glab mr view 123 --output json
//   glab api --paginate projects/.../pipelines/<id>/jobs

```

**`TestGetChecksFallsBackForVariantUnsupportedMRFlagErrors`** codifies this by injecting an "unrecognized arguments: --mr" error and asserting that the fallback path activates correctly.

## Scoped Authentication and Robust Output Parsing

### Host-Aware Auth Checks

The `Available` function (lines 21–33) prevents stale credentials for other GitLab instances from causing false negatives. When the repository host is known, it executes `glab auth status --hostname <host>` to scope the authentication check only to that instance. If the host is unknown, the backend gracefully falls back to the legacy unscoped call.

```go
// Example: scoped authentication – only the repo’s host is consulted.
if err := host.Available(ctx); err != nil {
    // Authentication failed for the specific host.
}

```

**`TestAvailableScopesAuthToConfiguredHost`** validates that the host-scoped auth call is issued when a host is configured.

### Paginated API Calls and JSON Trimming

For detached-HEAD environments, the backend cannot rely solely on local git context. Instead, `pipelineJobsArgs` builds a `glab api --paginate` command (lines 95–108) to fetch pipeline jobs directly through the GitLab REST API. The `--paginate` flag is always included so that jobs spread across multiple result pages are fully retrieved.

Because different glab releases may prepend banner notices before JSON output, the helper `bytesTrimToJSON` (lines 92–100) strips any leading non-JSON text before the decoder processes the payload. This ensures consistent parsing regardless of CLI preamble formatting.

**`TestGetChecksPaginatesJobsAcrossConcatenatedPages`** confirms that concatenated paginated JSON is parsed correctly.

## Summary

- The `FindPR` method avoids the `--state` flag removed in glab v1.5x, relying on open-by-default `mr list` behavior to preserve **glab version compatibility**.
- `GetChecks` probes for the `--mr` flag and uses `isUnsupportedMRFlagError` to trigger a fallback to `glab mr view` plus `glab api` when the flag is unrecognized.
- Authentication checks in `Available` are scoped to the repository host via `--hostname`, preventing false negatives from unrelated credentials.
- `pipelineJobsArgs` always includes `--paginate` for complete job retrieval, while `bytesTrimToJSON` sanitizes noisy CLI output before parsing.
- Tests such as `TestFindPRDoesNotPassRemovedStateFlag` and `TestGetChecksFallsBackForVariantUnsupportedMRFlagErrors` lock these compatibility behaviors in place.

## Frequently Asked Questions

### How does no-mistakes avoid breaking when glab removes a flag?

The backend never passes the removed `--state` flag to `glab mr list`. In [`internal/scm/gitlab/gitlab.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/scm/gitlab/gitlab.go) (lines 68–71), `FindPR` deliberately omits the flag because it was dropped in glab v1.5x, relying instead on the CLI's default of listing open merge requests.

### What happens if `glab ci status --mr` is unsupported?

`GetChecks` tries the modern command first. If `isUnsupportedMRFlagError` (lines 94–115) detects an unknown-flag error in `stderr`, the backend routes to `getChecksFallback`, which gathers the same data through `glab mr view` and paginated `glab api` calls compatible with older releases.

### Why does the GitLab backend scope `glab auth status` to a specific host?

`Available` passes `--hostname <host>` (lines 21–33) so authentication validation only considers credentials for that specific GitLab instance. This avoids false negatives caused by stale or unrelated host configurations in the user's glab CLI setup.

### How does the backend handle glab versions that print banners before JSON?

The `bytesTrimToJSON` helper (lines 92–100) discards any leading non-JSON text before decoding. This ensures consistent parsing regardless of whether the installed glab version prints notices, warnings, or other preamble content.