{"record":{"id":"642c745a624f6d1d","repo":"JuliusBrussee/caveman","slug":"postgres-set-organization-scope-w","errorCode":null,"errorMessage":"postgres: set organization scope: %w","messagePattern":"postgres: set organization scope: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/postgresconfig/postgresconfig.go","lineNumber":775,"sourceCode":"\t}\n\treturn nil\n}\n\n// WithOrg runs fn inside a transaction whose tenant GUC is transaction-local.\n// Empty scopes are rejected: tenant work must never degrade to an unscoped\n// query when RLS is the hard boundary.\nfunc WithOrg(ctx context.Context, pool *pgxpool.Pool, orgID string, fn func(pgx.Tx) error) error {\n\torgID = strings.TrimSpace(orgID)\n\tif orgID == \"\" {\n\t\treturn errors.New(\"postgres: organization scope is required\")\n\t}\n\ttx, err := pool.Begin(ctx)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() { _ = tx.Rollback(ctx) }()\n\tif _, err := tx.Exec(ctx, `SELECT set_config('app.current_organization_id', $1, true)`, orgID); err != nil {\n\t\treturn fmt.Errorf(\"postgres: set organization scope: %w\", err)\n\t}\n\tif err := fn(tx); err != nil {\n\t\treturn err\n\t}\n\treturn tx.Commit(ctx)\n}\n","sourceCodeStart":757,"sourceCodeEnd":782,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/shared/platform/postgresconfig/postgresconfig.go#L757-L782","documentation":"WithOrg begins a transaction and sets the transaction-local tenant GUC app.current_organization_id via set_config before running fn. This error wraps a failure executing that set_config statement, meaning the organization scope could not be established and the transaction is rolled back. Without the GUC, RLS policies would fail or leak, so the library refuses to proceed.","triggerScenarios":"Calling WithOrg with a valid orgID but tx.Exec('SELECT set_config(...)') errors — connection failure, context canceled, or driver-level error during Exec.","commonSituations":"Network drop right after Begin; context deadline during a busy transaction pool; Postgres rejecting set_config due to a session-level restriction or custom GUC placement rules in hardened setups.","solutions":["Check the wrapped error: for context timeout, increase the request timeout or pool capacity","For connection errors, verify DB connectivity and retry WithOrg","Confirm no server-side hooks (e.g. reserved-prefix GUC policies) block setting app.current_organization_id","Note the deferred Rollback already ran — the caller must retry the whole WithOrg call"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if orgID == \"\" { return errors.New(\"WithOrg requires a non-empty organization id\") }","typeGuard":null,"tryCatchPattern":"err := pool.WithOrg(ctx, orgID, func(tx pgx.Tx) error { ... })\nif err != nil {\n    if strings.Contains(err.Error(), \"set organization scope\") {\n        // transient DB issue: safe to retry the whole WithOrg call\n    }\n    return err\n}","preventionTips":["Keep WithOrg transactions short so connections don't drop mid-scope","Use context timeouts that comfortably cover the work done inside fn","Never set app.current_organization_id manually outside WithOrg"],"tags":["postgres","tenant-scoping","transaction","set-config"],"backgroundTag":"database-query-failed","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}