plandex-ai/plandex · error
Error storing plan build result: %v
Error message
Error storing plan build result: %v
What it means
After storing the per-file plan result inside a repo write lock (db.StorePlanResult) or acquiring the lock itself via db.ExecRepoOperation, any error is wrapped/logged as "Error storing plan build result: %v" and pushed to StreamDoneCh as a 500 ApiError. It indicates the persistence step of the file build failed — either the repo lock couldn't be acquired (canceled, timed out, deadlocked) or the database write for the PlanFileResult failed.
Source
Thrown at app/server/model/plan/build_finish.go:222
Reason: "store plan result",
}, func(repo *db.GitRepo) error {
log.Println("Storing plan result", planRes.Path)
err := db.StorePlanResult(planRes)
if err != nil {
log.Printf("Error storing plan result: %v\n", err)
return err
}
return nil
})
if err != nil {
log.Printf("Error storing plan build result: %v\n", err)
go notify.NotifyErr(notify.SeverityError, fmt.Errorf("error storing plan build result: %v", err))
activePlan.StreamDoneCh <- &shared.ApiError{
Type: shared.ApiErrorTypeOther,
Status: http.StatusInternalServerError,
Msg: "Error storing plan build result: " + err.Error(),
}
return
}
fileState.builderRun.FinishedAt = time.Now()
hooks.ExecHook(hooks.DidFinishBuilderRun, hooks.HookParams{
Auth: fileState.auth,
Plan: fileState.plan,
DidFinishBuilderRunParams: &fileState.builderRun,
})
log.Printf("Finished building file %s - setting activeBuild.Success to true\n", filePath)
// log.Println(spew.Sdump(activeBuild))
fileState.onBuildProcessed(activeBuild)
}View on GitHub (pinned to e2d772072e)
Solutions
- Read the full wrapped error in the server log to distinguish a lock-acquisition failure from a StorePlanResult DB error
- Verify the database is reachable and healthy (connection pool, disk space, migrations)
- Retry the plan build if the failure was transient (DB restart, lock contention)
- Check for leaked repo locks from crashed builds and ensure ExecRepoOperation releases locks (look for stale lock rows/locks for the plan branch)
- Avoid canceling plans mid-build when possible; cancelations can leave operations racing for locks
Defensive patterns
Strategy: retry
Validate before calling
// before starting builds, verify DB reachability
if err := db.Ping(); err != nil {
return fmt.Errorf("database unreachable before plan build: %v", err)
} Try / catch
err := db.ExecRepoOperation(params, func(repo *db.GitRepo) error {
return db.StorePlanResult(planRes)
})
if err != nil {
switch {
case errors.Is(err, context.Canceled):
// user canceled; don't retry
case isLockTimeout(err):
// retry with backoff
default:
// DB error: check database health, then retry or alert
}
} Prevention
- Monitor Postgres health and disk space during builds
- Keep repo write-lock scope short so concurrent builds don't time out
- Implement bounded retries with backoff for transient lock/DB errors
- Ensure plan cancellation reliably releases held repo locks
When it happens
Trigger: db.ExecRepoOperation fails to get the write lock (another build holds it, plan context canceled, lock timeout) or db.StorePlanResult returns a database error (connection refused, constraint violation, disk full) for planRes.Path.
Common situations: Postgres down or restarting during a build; concurrent builds on the same plan/branch contending for the repo write lock; plan canceled by the user mid-build so the context is canceled; disk exhaustion on the database volume.
Related errors
- error getting plan modelContext: %v
- error getting pending builds by path: %v
- error starting transaction: %v
- error scanning repo lock: %v
- error iterating over repo locks: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/8124fca906b934ca.
Report an issue: GitHub.