Skip to content

fix(server): tell the user when a repository lookup finds nothing - #8371

Closed
msegec wants to merge 1 commit into
pingdotgg:mainfrom
msegec:fix/lookup-error-detail
Closed

fix(server): tell the user when a repository lookup finds nothing#8371
msegec wants to merge 1 commit into
pingdotgg:mainfrom
msegec:fix/lookup-error-detail

Conversation

@msegec

@msegec msegec commented Aug 27, 2026

Copy link
Copy Markdown

Typing a repository path that does not resolve in the add-project GitHub flow showed "Source control repository operation lookupRepository failed for github: The source control operation could not be completed." The real cause, gh answering "Could not resolve to a Repository", was classified as a generic command failure, and the repository service replaces every provider detail with that generic sentence.

Three small pieces fix it end to end. VcsProcess now classifies gh's repository resolution stderr as a dedicated repository-not-found kind. GitHubCli maps that kind to a new GitHubRepositoryNotFoundError whose detail says "Repository not found. Check the owner/repo path and try again." The GitHub provider opts its compile-time constant details into a new userDetail field on SourceControlProviderError, and the repository service surfaces userDetail to the client while free-text provider detail still never reaches the wire. The toast now reads "Repository lookup failed: ... Repository not found. Check the owner/repo path and try again."

Verification: focused tests on VcsProcess (11), GitHubCli (13), SourceControlRepositoryService (10), GitLabCli (9), plus typecheck and lint for apps/server and packages/contracts.

Written by Claude Fable 5 in Claude Code.


Note

Low Risk
Error-mapping and user-facing messaging only; no auth, persistence, or clone/push behavior changes beyond clearer failures on lookup.

Overview
When a GitHub repository path does not resolve during add-project lookup, users now see a specific “repository not found” message instead of the generic “source control operation could not be completed” toast.

VCS classification: gh stderr that mentions resolving a Repository is classified as repository-not-found (distinct from pull-request not-found). That kind maps through contracts to a short server-side detail (“Repository not found.”).

GitHub CLI layer: A new GitHubRepositoryNotFoundError carries the user-facing line: check the owner/repo path and try again.

Safe client messaging: SourceControlProviderError gains optional userDetail for compile-time-safe text. The GitHub provider sets userDetail on getRepositoryCloneUrls failures. SourceControlRepositoryService prefers userDetail for the repository error detail sent to the client; raw provider detail (which may echo CLI output) still does not leak when userDetail is omitted.

GitLab continues to fold repository-not-found into its generic command error—no dedicated MR/repo split there in this change.

Reviewed by Cursor Bugbot for commit 33f179f. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Surface a user-safe message when repository lookup finds nothing

  • Adds a new "repository-not-found" literal to VcsProcessExitFailureKind in vcs.ts and classifies gh exits whose stderr contains "could not resolve to a repository" as this kind in VcsProcess.ts.
  • Maps that kind to a new GitHubRepositoryNotFoundError in GitHubCli.ts, which carries a curated detail string.
  • Adds an optional userDetail field to SourceControlProviderError in sourceControl.ts, and threads it through GitHubSourceControlProvider and SourceControlRepositoryService.ts so service errors surface the provider's detail instead of a generic message.
  • Risk: GitHubCliError union gains a new _tag variant GitHubRepositoryNotFoundError; any out-of-tree consumers narrowing on that union need to handle the new tag.

Macroscope summarized 33f179f.

A typo in the add-project GitHub path surfaced as 'The source control
operation could not be completed.' because gh's repository resolution
failure was classified as a generic command failure and the service
replaced every provider detail with that sentence.

gh stderr saying 'could not resolve to a repository' now classifies as
repository-not-found, GitHubCli maps it to a dedicated error, and the
provider opts curated constant details into the client-facing message
through a new userDetail field. Free-text provider detail still never
reaches the wire.
@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ae7d5d90-93fd-4aea-8a4c-828b1a4d0ba6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 27, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Effect service conventions review: one finding on how the new user-facing detail is modeled. See inline comments.

Posted via Macroscope — Effect Service Conventions

Comment on lines +163 to +169
/**
* Set only to a compile-time constant that is safe to show the user.
* `detail` may quote provider output and stays out of client-facing
* errors; `userDetail` is the adapter's explicit opt-in to surface a
* curated explanation instead of the generic fallback.
*/
userDetail: Schema.optional(Schema.String),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

userDetail adds a free-form, prose string field whose only guarantee is the surrounding comment, and it duplicates detail at its single production construction site (GitHubSourceControlProvider.getRepositoryCloneUrls passes userDetail: error.detail). The distinction it encodes ("this failure is a repository lookup miss, and here is the sentence for it") already exists structurally as GitHubRepositoryNotFoundError / VcsProcessExitFailureKind.

Consider modeling it structurally instead of threading text: a dedicated not-found error class (or a reason literal on SourceControlRepositoryError) whose detail/message is derived from the tag/reason, keeping the provider error as cause. That keeps error attributes bounded and the caller-visible sentence owned by the error type rather than copied through two layers.

Posted via Macroscope — Effect Service Conventions

Comment on lines +51 to +56
// Provider `detail` may quote provider output, so only the curated
// `userDetail` opt-in reaches the client; everything else stays
// behind the generic sentence.
detail:
(isSourceControlProviderError(cause) ? cause.userDetail : undefined) ??
"The source control operation could not be completed.",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wrapper's detail — and therefore SourceControlRepositoryError.message — is now taken from the cause's string field rather than from the wrapper's own structural attributes. Suggest classifying the provider failure here (e.g. on its tag/failureKind) into a structured reason or a distinct not-found error class, and deriving the user-facing sentence from that, so the message stays independent of provider-supplied text.

Posted via Macroscope — Effect Service Conventions

@macroscopeapp

macroscopeapp Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This is a focused GitHub repository-lookup error-message fix with limited runtime impact and focused tests. It also changes a shared error contract by propagating optional prose between layers, and unresolved design concerns about that representation warrant human review.

You can add or adjust custom eligibility rules. Learn more.

@msegec

msegec commented Aug 27, 2026

Copy link
Copy Markdown
Author

Folded into #8329, which already covers the add-project lookup flow.

@msegec msegec closed this Aug 27, 2026
@msegec
msegec deleted the fix/lookup-error-detail branch August 27, 2026 08:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant