plandex-ai/plandex · error
orgId is required
Error message
orgId is required
What it means
lockRepoDB validates LockRepoParams before touching the database: OrgId must be non-empty because every repo lock row is scoped to an org. If it is empty, lockRepoDB returns immediately with "orgId is required" without attempting a transaction.
Source
Thrown at app/server/db/locks.go:96
initialJitter := time.Duration(rand.Int63n(int64(5000 * time.Microsecond)))
select {
case <-params.Ctx.Done():
return "", params.Ctx.Err()
case <-time.After(initialJitter):
}
orgId := params.OrgId
userId := params.UserId
planId := params.PlanId
branch := params.Branch
scope := params.Scope
planBuildId := params.PlanBuildId
ctx := params.Ctx
cancelFn := params.CancelFn
if orgId == "" {
return "", fmt.Errorf("orgId is required")
}
if planId == "" {
return "", fmt.Errorf("planId is required")
}
if scope != LockScopeRead && scope != LockScopeWrite {
return "", fmt.Errorf("invalid lock scope: %s", scope)
}
tx, err := Conn.BeginTxx(ctx, &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
if err != nil {
if locksVerboseLogging {
log.Printf("[Lock][%d] Error starting transaction %v | reason: %s",
goroutineID, err, params.Reason)
}
return "", fmt.Errorf("error starting transaction: %v", err)
}
var committed boolView on GitHub (pinned to e2d772072e)
Solutions
- Populate LockRepoParams.OrgId from the authenticated user's org before calling the lock API.
- Add a precondition check or constructor for LockRepoParams that rejects empty OrgId at the call site.
- Trace where the empty value originates — usually an unauthenticated request or an org not attached to the plan.
Example fix
// before
params := db.LockRepoParams{PlanId: planId, UserId: userId, Scope: db.LockScopeWrite}
// after
params := db.LockRepoParams{OrgId: orgId, PlanId: planId, UserId: userId, Scope: db.LockScopeWrite}
if orgId == "" { return fmt.Errorf("cannot lock plan without an org") } Defensive patterns
Strategy: validation
Validate before calling
func validateLockParams(p db.LockRepoParams) error {
if p.OrgId == "" { return errors.New("orgId must be set before locking") }
return nil
} Type guard
func hasOrgId(p db.LockRepoParams) bool { return strings.TrimSpace(p.OrgId) != "" } Try / catch
if err := validateLockParams(params); err != nil { return err }
lockId, err := db.LockRepo(ctx, cancel, params)
if err != nil { return fmt.Errorf("lock failed: %w", err) } Prevention
- Use a constructor (NewLockRepoParams) that requires orgId so zero-value structs are impossible.
- Derive orgId from the authenticated session, never from client-supplied body fields.
- Add a unit test asserting lock calls with empty orgId fail fast at your boundary.
When it happens
Trigger: Constructing LockRepoParams without setting OrgId (zero-value struct passed to LockRepo / LockRepoDB), or clearing the field when copying params between calls.
Common situations: Refactoring added a new lock call site and the org id wasn't threaded through; org id loaded from a session/config that was empty in a dev environment; partial struct literal omitted OrgId.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- planId is required
- invalid lock scope: %s
- invalid lock scope: %v
- error prompting host: %v
- error prompting email: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/ed62d569bc53ce7f.
Report an issue: GitHub.