Handle deleted git directories as non-repositories#1907
Conversation
- Treat deleted/missing cwd paths as explicit non-repo status - Cover GitCore and GitManager with integration tests
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
- Normalize PR title, URL, and branch names before publishing status - Skip entries whose required fields become empty after trimming
ApprovabilityVerdict: Approved This PR adds defensive error handling for deleted git directories (returning non-repo status instead of erroring) and refactors GitHub PR JSON parsing into a shared module. Both changes have comprehensive test coverage, the author is the primary maintainer of these files, and there are no security or significant runtime implications beyond the intended edge case fix. You can customize Macroscope's approvability policy. Learn more. |
- Trim GitHub CLI pull request fields before use - Share PR JSON decoding between GitHub CLI and git manager - Improve errors when gh returns invalid PR JSON
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Strict array decode replaces lenient per-entry skipping
- Changed decodeGitHubPullRequestListJson to first parse the JSON as an array of unknowns, then decode each entry individually with Schema.decodeUnknownExit, skipping invalid entries instead of failing the entire list.
Or push these changes by commenting:
@cursor push dce2f708e0
Preview (dce2f708e0)
diff --git a/apps/server/src/git/githubPullRequests.ts b/apps/server/src/git/githubPullRequests.ts
--- a/apps/server/src/git/githubPullRequests.ts
+++ b/apps/server/src/git/githubPullRequests.ts
@@ -1,4 +1,4 @@
-import { Cause, Result, Schema } from "effect";
+import { Cause, Exit, Result, Schema } from "effect";
import { PositiveInt, TrimmedNonEmptyString } from "@t3tools/contracts";
import { decodeJsonResult, formatSchemaError } from "@t3tools/shared/schemaJson";
@@ -84,7 +84,8 @@
};
}
-const decodeGitHubPullRequestList = decodeJsonResult(Schema.Array(GitHubPullRequestSchema));
+const decodeJsonArray = decodeJsonResult(Schema.Array(Schema.Unknown));
+const decodeGitHubPullRequestEntry = Schema.decodeUnknownExit(GitHubPullRequestSchema);
const decodeGitHubPullRequest = decodeJsonResult(GitHubPullRequestSchema);
export const formatGitHubJsonDecodeError = formatSchemaError;
@@ -95,11 +96,19 @@
ReadonlyArray<NormalizedGitHubPullRequestRecord>,
Cause.Cause<Schema.SchemaError>
> {
- const result = decodeGitHubPullRequestList(raw);
- if (Result.isSuccess(result)) {
- return Result.succeed(result.success.map(normalizeGitHubPullRequestRecord));
+ const arrayResult = decodeJsonArray(raw);
+ if (!Result.isSuccess(arrayResult)) {
+ return Result.fail(arrayResult.failure);
}
- return Result.fail(result.failure);
+
+ const normalized: NormalizedGitHubPullRequestRecord[] = [];
+ for (const entry of arrayResult.success) {
+ const decoded = decodeGitHubPullRequestEntry(entry);
+ if (Exit.isSuccess(decoded)) {
+ normalized.push(normalizeGitHubPullRequestRecord(decoded.value));
+ }
+ }
+ return Result.succeed(normalized);
}
export function decodeGitHubPullRequestJson(You can send follow-ups to the cloud agent here.
- Skip malformed or blank GitHub PR list entries instead of failing the whole parse - Keep valid PRs normalized so status can still report directories with usable matches - Add regression coverage for CLI and manager PR listing
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: State normalization drops lowercase "merged" and "closed" handling
- Added
toUpperCase()normalization of the state string before comparison, so both lowercase and uppercase variants (e.g., "merged", "MERGED") are correctly matched.
- Added
Or push these changes by commenting:
@cursor push 7ae5b33934
Preview (7ae5b33934)
diff --git a/apps/server/src/git/githubPullRequests.ts b/apps/server/src/git/githubPullRequests.ts
--- a/apps/server/src/git/githubPullRequests.ts
+++ b/apps/server/src/git/githubPullRequests.ts
@@ -50,13 +50,14 @@
state?: string | null | undefined;
mergedAt?: string | null | undefined;
}): "open" | "closed" | "merged" {
+ const upperState = typeof input.state === "string" ? input.state.toUpperCase() : undefined;
if (
(typeof input.mergedAt === "string" && input.mergedAt.trim().length > 0) ||
- input.state === "MERGED"
+ upperState === "MERGED"
) {
return "merged";
}
- if (input.state === "CLOSED") {
+ if (upperState === "CLOSED") {
return "closed";
}
return "open";You can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit 6f6e035. Configure here.
- Treat lowercase `merged` and `closed` states from `gh` JSON as expected - Add a GitManager test covering lowercase PR states
Dismissing prior approval to re-evaluate 99e0eb4


Summary
cwdpaths as explicit non-repository states instead of surfacing git/fs errors.GitCoreso status callers return stable defaults for deleted directories.statusDetails, branch lookup, and manager-level status handling to degrade cleanly when the working directory no longer exists.GitCoreandGitManagerto verify deleted directories returnisRepo: falsewith empty status data.Testing
bun run test apps/server/src/git/Layers/GitCore.test.tsbun run test apps/server/src/git/Layers/GitManager.test.tsbun fmtbun lintbun typecheckNote
Medium Risk
Changes error-handling paths in
GitCore/GitManagerso missing working directories and upstream refresh failures now degrade to non-repo defaults instead of surfacing errors, which can affect status/branch reporting behavior. Adds shared GitHub PR JSON decoding/normalization that may change how PR metadata is accepted/filtered fromghoutput.Overview
Treat deleted/missing git working directories as explicit non-repositories.
GitCore.statusDetailsLocal,statusDetails, andlistBranchesnow detect “missing cwd” failures and return stableisRepo: falseresults (via a newNON_REPOSITORY_STATUS_DETAILSconstant) rather than throwing.Centralize and tighten GitHub PR JSON parsing. Adds
githubPullRequests.tsto decode/normalizeghPR JSON (trims fields, normalizes state, skips invalid entries) and updatesGitHubCliandGitManagerto use it with clearer schema-formatted errors.Tests updated/added to cover deleted-directory behavior for
GitCore/GitManagerand PR metadata trimming/invalid-entry filtering inGitHubCliand manager status.Reviewed by Cursor Bugbot for commit 99e0eb4. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Handle deleted git directories as non-repositories in status and branch listing
listBranches,statusDetails, andstatusDetailsLocalinGitCore.tsnow return a non-repository result instead of throwing when the working directory no longer exists on disk.isMissingGitCwdErrorto detect ENOENT/invalid-directory errors from git commands, and aNON_REPOSITORY_STATUS_DETAILSconstant as the canonical non-repo response.githubPullRequests.tsmodule with schema-driven normalization;GitHubCliandGitManagernow use these shared decoders instead of ad-hoc parsing.Macroscope summarized 99e0eb4.