{"record":{"id":"0e5be294fcd1438d","repo":"plandex-ai/plandex","slug":"error-getting-pending-invites-for-org-v","errorCode":null,"errorMessage":"error getting pending invites for org: %v","messagePattern":"error getting pending invites for org: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/invite_helpers.go","lineNumber":57,"sourceCode":"\terr := Conn.Get(&invite, \"SELECT * FROM invites WHERE org_id = $1 AND email = $2 AND accepted_at IS NULL\", orgId, email)\n\n\tif err != nil {\n\t\tif err == sql.ErrNoRows {\n\t\t\treturn nil, nil\n\t\t}\n\n\t\treturn nil, fmt.Errorf(\"error getting invite: %v\", err)\n\t}\n\n\treturn &invite, nil\n}\n\nfunc ListPendingInvites(orgId string) ([]*Invite, error) {\n\tvar invites []*Invite\n\terr := Conn.Select(&invites, \"SELECT * FROM invites WHERE org_id = $1 AND accepted_at IS NULL\", orgId)\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting pending invites for org: %v\", err)\n\t}\n\n\treturn invites, nil\n}\n\nfunc ListAllInvites(orgId string) ([]*Invite, error) {\n\tvar invites []*Invite\n\terr := Conn.Select(&invites, \"SELECT * FROM invites WHERE org_id = $1\", orgId)\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting all invites for org: %v\", err)\n\t}\n\n\treturn invites, nil\n}\n\nfunc ListAcceptedInvites(orgId string) ([]*Invite, error) {\n\tvar invites []*Invite","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/invite_helpers.go#L39-L75","documentation":"ListPendingInvites selects all unaccepted invites for an org via Conn.Select. Unlike single-row getters, Select doesn't return sql.ErrNoRows for empty results, so ANY error here — including connection issues — is wrapped as this error. Empty result sets return a nil slice without error.","triggerScenarios":"Conn.Select(\"SELECT * FROM invites WHERE org_id = $1 AND accepted_at IS NULL\", orgId) fails: invalid org_id type/format (uuid cast error), DB connection failure/timeout, or invites table schema drift (SELECT * column scan mismatch against the Invite struct).","commonSituations":"ListPendingInvitesHandler called for an org id with wrong format, server deployed against an unmigrated database so SELECT * returns columns the Invite struct can't scan, or transient DB outage.","solutions":["Check the wrapped cause: unknown column / scan errors mean migrations are out of date — run them.","Validate orgId format before the call if the column is uuid.","Verify DB connectivity and connection-pool configuration.","Prefer explicit column lists over SELECT * to decouple the query from schema drift.","Note an empty pending list is a nil slice with nil error — no fix needed for that case."],"exampleFix":"// before (fragile to schema drift)\nerr := Conn.Select(&invites, \"SELECT * FROM invites WHERE org_id = $1 AND accepted_at IS NULL\", orgId)\n\n// after\nerr := Conn.Select(&invites, \"SELECT id, org_id, email, name, inviter_id, org_role_id, created_at FROM invites WHERE org_id = $1 AND accepted_at IS NULL\", orgId)","handlingStrategy":"try-catch","validationCode":"if _, err := uuid.Parse(orgId); err != nil {\n    return fmt.Errorf(\"invalid org id %q\", orgId)\n}","typeGuard":null,"tryCatchPattern":"invites, err := db.ListPendingInvites(orgId)\nif err != nil {\n    var pgErr *pq.Error\n    if errors.As(err, &pgErr) && pgErr.Code == \"42P01\" {\n        return fmt.Errorf(\"invites table missing — run migrations: %w\", err)\n    }\n    return fmt.Errorf(\"list pending invites: %w\", err)\n}","preventionTips":["Run DB migrations as part of every deploy before serving traffic.","Avoid SELECT * against structs; list columns explicitly to survive schema drift.","Validate orgId format at the handler boundary.","Set up DB health checks and alert on connection failures.","Treat a nil slice as a normal empty result, not an error."],"tags":["database","sql","select","list","schema-drift"],"backgroundTag":"database-query-failed","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"}