ruvnet/ruflo · error

Transaction is not active. Call begin() first.

Error message

Transaction is not active. Call begin() first.

What it means

Thrown by StreamingVectorClient's transaction wrapper (ruvector streaming.ts) from the private ensureActive() guard. Every transactional method (insert, update, delete, query) calls ensureActive() first, which checks the isActive flag set only by begin(). If the transaction was never started, or was already committed/rolled back, any further operation throws this error.

Source

Thrown at v3/@claude-flow/plugins/src/integrations/ruvector/streaming.ts:1204

    savepoints: string[];
    queryCount: number;
    durationMs: number;
  } {
    return {
      transactionId: this.transactionId,
      isActive: this.isActive,
      savepoints: Array.from(this.savepoints),
      queryCount: this.queryCount,
      durationMs: this.startTime ? Date.now() - this.startTime : 0,
    };
  }

  /**
   * Ensure transaction is active.
   */
  private ensureActive(): void {
    if (!this.isActive) {
      throw new Error('Transaction is not active. Call begin() first.');
    }
  }

  /**
   * Build search query SQL.
   */
  private buildSearchQuery(options: VectorSearchOptions): { sql: string; params: unknown[] } {
    const tableName = options.tableName ?? this.defaultTableName;
    const vectorColumn = options.vectorColumn ?? 'embedding';
    const metric = options.metric ?? 'cosine';
    const operator = DISTANCE_OPERATORS[metric] ?? '<=>';

    const queryVector = this.formatVector(options.query);
    const schemaPrefix = this.schema ? `${this.escapeIdentifier(this.schema)}.` : '';

    const selectColumns = options.selectColumns ?? ['id'];
    const columnList = [...selectColumns];

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Await tx.begin() before any other call on the transaction object
  2. If the error appears mid-flow, check whether commit() or rollback() was already called earlier (e.g. in an early-return branch) and get a fresh transaction instead of reusing the object
  3. Wrap the whole unit of work in a helper that always begins and always commits/rollbacks, so begin() cannot be skipped
  4. Inspect tx.getStatus().isActive after begin() when the connection is flaky, to confirm the transaction really started

Example fix

// before
const tx = await client.transaction();
await tx.insert({ vectors }); // throws: Transaction is not active
await tx.commit();

// after
const tx = await client.transaction();
await tx.begin();
try {
  await tx.insert({ vectors });
  await tx.commit();
} catch (err) {
  await tx.rollback();
  throw err;
}
Defensive patterns

Strategy: validation

Validate before calling

// Check transaction liveness via the public status API before operating
const status = tx.getStatus();
if (!status.isActive) {
  await tx.begin();
}
await tx.insert({ vectors });

Type guard

function isActiveTransaction(tx: { getStatus(): { isActive: boolean } }): boolean {
  return tx.getStatus().isActive;
}

Try / catch

try {
  await tx.query(sql);
} catch (err) {
  if (err instanceof Error && err.message.includes('Transaction is not active')) {
    // restart the unit of work on a fresh transaction
    await tx.begin();
    return tx.query(sql);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling tx.insert()/update()/delete()/query() on a transaction object without awaiting tx.begin() first; reusing the same transaction object after commit() or rollback() (isActive flips back to false); a begin() that failed (e.g. connection error) whose error was swallowed, then proceeding to query.

Common situations: Refactoring code that used the non-transactional client API into transactions and forgetting the begin() call; retry logic that reruns the transaction body but reuses the spent transaction object; early commit/rollback inside a loop followed by more statements; missing await on begin() so subsequent statements run before the flag is set.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/adec7563ae07b14a. Report an issue: GitHub.