Skip to content

bug: successful remote-repo report is discarded when the temporary checkout cannot be removed #68

Description

@aryamthecodebreaker

Summary

In withRepositorySource(), a failure to delete the temporary checkout throws even when the analysis succeeded, so a complete report is discarded and the CLI exits 1.

packages/cli/src/repository-source.ts:

} catch (error) {
  primaryError = error;
  throw error;
} finally {
  try {
    await removeTemporaryDirectory(temporaryRoot);
  } catch (cleanupError) {
    const cleanupMessage = `Could not remove temporary checkout "${temporaryRoot}": ...`;
    if (primaryError instanceof Error) {
      throw new RepositorySourceError(`${primaryError.message} ${cleanupMessage}`);
    }
    throw new RepositorySourceError(cleanupMessage);   // <- success path
  }
}

A throw inside finally replaces the pending return value. When work() returned a valid FixMapReport, that report is thrown away and the user sees only a cleanup error.

Why this matters in practice

The temporary directory is a freshly cloned git repo. Removing one is failure-prone on Windows — .git/objects pack files are written read-only, and Defender / Search Indexer routinely hold transient handles, yielding EPERM / EBUSY. The maxRetries: 3, retryDelay: 100 on rm reduces the window but does not close it.

So on Windows, fixmap plan --issue "..." --repo https://github.com/owner/repo can do all the work correctly and still fail with an unrelated cleanup message.

Secondary problem

When both the work and the cleanup fail, the original error is flattened into a string and rethrown as a RepositorySourceError. The original error type, cause, and stack are lost, so callers can no longer distinguish e.g. a clone failure from a scan failure.

Suggested fix

Treat cleanup as best-effort:

  • If work() succeeded, return the report and surface the cleanup failure as a ScanDiagnostic (severity: "warning") appended to report.diagnostics, mentioning the leftover path so the user can delete it.
  • If work() failed, rethrow the original error, attaching the cleanup failure via cause rather than string concatenation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions