plandex-ai/plandex · error

error checking out sha: %v

Error message

error checking out sha: %v

What it means

Returned from the get-current-plan-state repo operation when repo.GitCheckoutSha(sha) cannot check out the requested commit SHA in the plan's git repo (e.g. fatal: bad object / reference not found). The ExecRepoOperation closure aborts and the handler responds 500 'Error getting current plan state: error checking out sha'.

Source

Thrown at app/server/handlers/plans_changes.go:64

	log.Printf("locking with scope: %s", scope)

	var planState *shared.CurrentPlanState

	err := db.ExecRepoOperation(db.ExecRepoOperationParams{
		OrgId:    auth.OrgId,
		UserId:   auth.User.Id,
		PlanId:   planId,
		Branch:   branch,
		Scope:    scope,
		Ctx:      ctx,
		CancelFn: cancel,
		Reason:   "get current plan state",
	}, func(repo *db.GitRepo) error {
		var err error
		if sha != "" {
			err = repo.GitCheckoutSha(sha)
			if err != nil {
				return fmt.Errorf("error checking out sha: %v", err)
			}

			defer func() {
				checkoutErr := repo.GitCheckoutBranch(branch)
				if checkoutErr != nil {
					log.Printf("Error checking out branch: %v\n", checkoutErr)
				}
			}()
		}

		planState, err = db.GetCurrentPlanState(db.CurrentPlanStateParams{
			OrgId:  auth.OrgId,
			PlanId: planId,
		})

		if err != nil {
			return fmt.Errorf("error getting current plan state: %v", err)
		}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Verify the SHA exists in the plan repo (e.g. git cat-file -t <sha>) and pass a full 40-char SHA
  2. Omit the sha path segment to fetch the current branch state instead of a specific commit
  3. Re-fetch the plan's latest SHAs from the server if the plan history was rewritten or reset
  4. Check git repo health on the server (corrupt .git) if valid SHAs also fail

Example fix

// before: stale SHA from a rewritten history
GET /plans/{planId}/branches/main/changes/abc1234
// after: use current branch state
GET /plans/{planId}/branches/main/changes
Defensive patterns

Strategy: fallback

Validate before calling

// client-side sanity check before requesting a specific sha
if (sha && !/^[0-9a-f]{7,40}$/.test(sha)) {
  throw new Error('malformed sha: ' + sha)
}

Type guard

function isPlausibleSha(s) {
  return typeof s === 'string' && /^[0-9a-f]{7,40}$/.test(s)
}

Try / catch

try {
  state = await client.GetCurrentPlanState(planId, branch, sha)
} catch (err) {
  if (String(err.message).includes('error checking out sha')) {
    state = await client.GetCurrentPlanState(planId, branch) // fall back to branch head
  }
}

Prevention

When it happens

Trigger: GET the plan-state endpoint with a sha path parameter that does not exist in the plan repo: an abbreviated/unknown SHA, a SHA that was garbage-collected or rewritten by a force-push/rebase, or a SHA from a different branch.

Common situations: Client caches a SHA from a previous session after the plan was reset or its history rewritten; typo in the SHA; asking for a SHA created after a repo re-init.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/49d391036322c010. Report an issue: GitHub.