hyperledger/fabric · error

this function should only be called once on a transaction si

Error message

this function should only be called once on a transaction simulator instance

What it means

Returned by txSimulator.GetTxSimulationResults when it is invoked more than once on the same simulator instance. Simulation results are computed once; a second call would mutate an already-consumed rwset, so the guard rejects it.

Source

Thrown at core/ledger/kvledger/txmgmt/txmgr/tx_simulator.go:198

) (ledger.QueryResultsIterator, error) {
	if err := s.checkBeforePaginatedQueries(); err != nil {
		return nil, err
	}
	return s.queryExecutor.GetStateRangeScanIteratorWithPagination(namespace, startKey, endKey, pageSize)
}

// ExecuteQueryWithPagination implements method in interface `ledger.QueryExecutor`
func (s *txSimulator) ExecuteQueryWithPagination(namespace, query, bookmark string, pageSize int32) (ledger.QueryResultsIterator, error) {
	if err := s.checkBeforePaginatedQueries(); err != nil {
		return nil, err
	}
	return s.queryExecutor.ExecuteQueryWithPagination(namespace, query, bookmark, pageSize)
}

// GetTxSimulationResults implements method in interface `ledger.TxSimulator`
func (s *txSimulator) GetTxSimulationResults() (*ledger.TxSimulationResults, error) {
	if s.simulationResultsComputed {
		return nil, errors.New("this function should only be called once on a transaction simulator instance")
	}
	defer func() { s.simulationResultsComputed = true }()
	logger.Debugf("Simulation completed, getting simulation results")
	if s.queryExecutor.err != nil {
		return nil, s.queryExecutor.err
	}
	s.queryExecutor.addRangeQueryInfo()
	simResults, err := s.rwsetBuilder.GetTxSimulationResults()
	if err != nil {
		return nil, err
	}
	// The txSimulator structures need to be cloned so that subsequent RW set additions don't modify these TX simulation results
	simResults.PrivateReads = s.privateReads.Clone()
	simResults.WritesetMetadata = s.writesetMetadata.Clone()
	return simResults, nil
}

// ExecuteUpdate implements method in interface `ledger.TxSimulator`

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Call GetTxSimulationResults exactly once per simulator
  2. Create a new simulator for a repeat simulation
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at core/ledger/kvledger/txmgmt/txmgr/tx_simulator.go:198 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/b1e29f31eb369cf1. Report an issue: GitHub.