{"record":{"id":"bf65de0f0708f9c8","repo":"remix-run/remix","slug":"unknown-transaction-token-token-id-bf65de","errorCode":null,"errorMessage":"Unknown transaction token: + token.id","messagePattern":"Unknown transaction token: \\+ token\\.id","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/data-table-postgres/src/lib/driver.ts","lineNumber":230,"sourceCode":"\n    this.#transactions.set(token.id, {\n      client: transactionClient,\n      releaseOnClose,\n    })\n\n    return token\n  }\n\n  /**\n   * Commits an open postgres transaction.\n   * @param token Transaction token to commit.\n   * @returns A promise that resolves when the transaction is committed.\n   */\n  async commitTransaction(token: TransactionToken): Promise<void> {\n    let transaction = this.#transactions.get(token.id)\n\n    if (!transaction) {\n      throw new Error('Unknown transaction token: ' + token.id)\n    }\n\n    let failure: unknown\n    try {\n      await transaction.client.query('commit')\n    } catch (error) {\n      failure = error\n      throw error\n    } finally {\n      this.#transactions.delete(token.id)\n\n      if (transaction.releaseOnClose) {\n        if (failure === undefined) {\n          releasePostgresClient(transaction.client)\n        } else {\n          destroyPostgresClient(transaction.client, failure)\n        }\n      }","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/data-table-postgres/src/lib/driver.ts#L212-L248","documentation":"The Postgres driver keeps an internal map of open transactions keyed by token id. commitTransaction throws this when the supplied TransactionToken is not in that map — i.e. the transaction was already committed/rolled back, was created by a different driver instance, or the token was fabricated.","triggerScenarios":"Calling commitTransaction twice with the same token; committing after rollbackTransaction already removed it; using a token from one PostgresDatabase instance on another; keeping a token across driver close()/wipe() which clears transactions.","commonSituations":"Retry logic that re-commits on timeout; storing transaction tokens in shared state or caches; running tests that reuse a module-level driver but per-test tokens (or vice versa); committing after an error path already rolled back.","solutions":["Ensure commit/rollback is called exactly once per transaction token; clear the token reference afterwards","Use the driver's transaction helper (e.g. database.transaction(async tx => ...)) which manages the token lifecycle instead of manual begin/commit","Verify you are passing the token returned by beginTransaction on the same driver instance","Guard with hasOpenTransactions/driver state checks before manual commit if lifecycle is uncertain"],"exampleFix":"// before\nawait driver.commitTransaction(token)\n// ... later, in an error handler\nawait driver.commitTransaction(token) // throws\n\n// after\nlet done = false\ntry {\n  await driver.commitTransaction(token)\n  done = true\n} finally {\n  if (!done) await driver.rollbackTransaction(token).catch(() => undefined)\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await driver.commitTransaction(token) } catch (e) { if (e instanceof Error && e.message.startsWith('Unknown transaction token')) { /* already finished — treat as success */ return } throw e }","preventionTips":["Commit or rollback exactly once per token; null the reference after","Prefer the managed transaction API","Never reuse tokens across driver instances"],"tags":["postgres","transaction","token","driver"],"backgroundTag":"invalid-transaction-token","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}