{"record":{"id":"db6ff4c76de69e91","repo":"plandex-ai/plandex","slug":"error-getting-orgs-from-invites-v","errorCode":null,"errorMessage":"error getting orgs from invites: %v","messagePattern":"error getting orgs from invites: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/org_helpers.go","lineNumber":62,"sourceCode":"\n\t// access via invitation\n\tinvites, err := GetPendingInvitesForEmail(user.Email)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting invites for user: %v\", err)\n\t}\n\n\torgIds = []string{}\n\tfor _, invite := range invites {\n\t\torgIds = append(orgIds, invite.OrgId)\n\t\torgRoleIdByOrgId[invite.OrgId] = invite.OrgRoleId\n\t}\n\n\tif len(orgIds) > 0 {\n\t\tvar orgsFromInvites []*Org\n\t\tquery := fmt.Sprintf(\"SELECT %s FROM orgs WHERE id = ANY($1)\", orgFields)\n\t\terr = Conn.Select(&orgsFromInvites, query, pq.Array(orgIds))\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error getting orgs from invites: %v\", err)\n\t\t}\n\t\torgs = append(orgs, orgsFromInvites...)\n\t}\n\n\treturn orgs, nil\n}\nfunc GetOrg(orgId string) (*Org, error) {\n\tvar org Org\n\tquery := fmt.Sprintf(\"SELECT %s FROM orgs WHERE id = $1\", orgFields)\n\terr := Conn.Get(&org, query, orgId)\n\n\tif err != nil {\n\t\tif err == sql.ErrNoRows {\n\t\t\treturn nil, fmt.Errorf(\"org not found\")\n\t\t}\n\n\t\treturn nil, fmt.Errorf(\"error getting org: %v\", err)\n\t}","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/org_helpers.go#L44-L80","documentation":"The final wrapped failure in GetAccessibleOrgsForUser: the SELECT fetching org rows referenced by the user's pending invites. Fires when Conn.Select on orgsFromInvites fails (connection, missing table, nonexistent column in orgFields, or scan mismatch). Only runs when invite-derived orgIds is non-empty.","triggerScenarios":"orgs table missing or unreachable; orgFields names a column absent from orgs; Org struct cannot scan the returned columns; orgIds array passed via pq.Array is fine but the query errors for another driver reason.","commonSituations":"Schema drift between orgFields and the orgs table after a migration; an invite points at a deleted org (row simply absent — no error); DB restart during org listing.","solutions":["Read the wrapped error: 'column does not exist' → fix orgFields; scan error → align Org struct tags","Keep orgFields synchronized with the orgs schema","Run pending migrations","Consider INNER JOIN orgs to invites instead of two queries to avoid orphan-invite gaps"],"exampleFix":"// before\nquery := fmt.Sprintf(\"SELECT %s FROM orgs WHERE id = ANY($1)\", orgFields)\nerr = Conn.Select(&orgsFromInvites, query, pq.Array(orgIds))\n// after\nquery := fmt.Sprintf(\"SELECT DISTINCT o.%s FROM orgs o JOIN invites i ON i.org_id = o.id WHERE i.email = $1 AND i.status = 'pending'\", strings.ReplaceAll(orgFields, \", \", \", o.\"))","handlingStrategy":"try-catch","validationCode":"// startup: assert all orgFields columns exist on orgs\nconst orgFields = \"id, name, created_at, updated_at\"\nvar n int\nfor _, col := range strings.Split(orgFields, \", \") {\n    Conn.Get(&n, \"SELECT count(*) FROM information_schema.columns WHERE table_name='orgs' AND column_name=$1\", col)\n    // fail fast if n == 0\n}","typeGuard":"func isUndefinedColumn(err error) bool {\n    var pgErr *pgconn.PgError\n    return errors.As(err, &pgErr) && pgErr.Code == \"42703\"\n}","tryCatchPattern":"orgs, err := db.GetAccessibleOrgsForUser(user)\nif err != nil {\n    if isUndefinedColumn(errors.Unwrap(err)) { log.Printf(\"orgs schema drift: %v\", err) }\n    return err\n}","preventionTips":["Keep orgFields synchronized with the orgs schema after migrations","Prefer a single JOIN over the two-step orgIds query to reduce failure surface","Run migrations in every environment","Wrap with %w to preserve the driver error","Add a smoke test that lists orgs for a seeded user with invites"],"tags":["database","postgres","sqlx","schema-drift"],"backgroundTag":"sql-column-not-found","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}