{"record":{"id":"d9e7f9b2d8583d1c","repo":"jackc/pgx","slug":"tx-is-closed","errorCode":null,"errorMessage":"tx is closed","messagePattern":"tx is closed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tx.go","lineNumber":85,"sourceCode":"\tbuf.WriteString(\"begin\")\n\n\tif txOptions.IsoLevel != \"\" {\n\t\tbuf.WriteString(\" isolation level \")\n\t\tbuf.WriteString(string(txOptions.IsoLevel))\n\t}\n\tif txOptions.AccessMode != \"\" {\n\t\tbuf.WriteByte(' ')\n\t\tbuf.WriteString(string(txOptions.AccessMode))\n\t}\n\tif txOptions.DeferrableMode != \"\" {\n\t\tbuf.WriteByte(' ')\n\t\tbuf.WriteString(string(txOptions.DeferrableMode))\n\t}\n\n\treturn buf.String()\n}\n\nvar ErrTxClosed = errors.New(\"tx is closed\")\n\n// ErrTxCommitRollback occurs when an error has occurred in a transaction and\n// Commit() is called. PostgreSQL accepts COMMIT on aborted transactions, but\n// it is treated as ROLLBACK.\nvar ErrTxCommitRollback = errors.New(\"commit unexpectedly resulted in rollback\")\n\n// Begin starts a transaction. Unlike [database/sql], the context only affects the begin command. i.e. there is no\n// auto-rollback on context cancellation.\nfunc (c *Conn) Begin(ctx context.Context) (Tx, error) {\n\treturn c.BeginTx(ctx, TxOptions{})\n}\n\n// BeginTx starts a transaction with txOptions determining the transaction mode. Unlike [database/sql], the context only\n// affects the begin command. i.e. there is no auto-rollback on context cancellation.\nfunc (c *Conn) BeginTx(ctx context.Context, txOptions TxOptions) (Tx, error) {\n\t_, err := c.Exec(ctx, txOptions.beginSQL())\n\tif err != nil {\n\t\t// begin kills the connection upon receiving fatal, panic or non PGError errors,","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/jackc/pgx/blob/ec1a0befd22592cffffdeeb0a50311b506372f4c/tx.go#L67-L103","documentation":"Sentinel ErrTxClosed: the operation (Begin, Commit, Rollback, etc.) was invoked on a transaction that is already closed — committed, rolled back, or otherwise finished. The stale Tx handle is the faulty input; detect it with errors.Is since it may be returned directly or wrapped.","triggerScenarios":"Thrown at tx.go:85 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Use the Tx only between Begin and Commit/Rollback; do not reuse it afterwards","Track transaction state in calling code instead of retrying operations on a finished Tx","Check with errors.Is(err, pgx.ErrTxClosed) where relevant"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"ec1a0befd22592cffffdeeb0a50311b506372f4c","analyzedAt":"2026-08-04T22:52:11.263Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}