How the no-mistakes GitLab Backend Handles glab Version Compatibility

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 (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.

// 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.

// 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.

// 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 (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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →