temporalio/temporal · error
rowsAffected returned %v shards instead of one
Error message
rowsAffected returned %v shards instead of one
What it means
Same create-shard verification path: the INSERT of a shard row must affect exactly 1 row; any other count causes this error. It guarantees one canonical shard row per shardID, so a non-1 count is treated as a storage invariant violation.
Source
Thrown at common/persistence/sql/shard.go:109
m.logger,
); err != nil {
return err
}
result, err := tx.UpdateShards(ctx, &sqlplugin.ShardsRow{
ShardID: request.ShardID,
RangeID: request.RangeID,
Data: request.ShardInfo.Data,
DataEncoding: request.ShardInfo.EncodingType.String(),
})
if err != nil {
return err
}
rowsAffected, err := result.RowsAffected()
if err != nil {
return fmt.Errorf("rowsAffected returned error for shardID %v: %v", request.ShardID, err)
}
if rowsAffected != 1 {
return fmt.Errorf("rowsAffected returned %v shards instead of one", rowsAffected)
}
return nil
})
}
func (m *sqlShardStore) AssertShardOwnership(
ctx context.Context,
request *persistence.AssertShardOwnershipRequest,
) error {
// AssertShardOwnership is not implemented for sql shard store
return nil
}
// initiated by the owning shard
func lockShard(
ctx context.Context,
tx sqlplugin.Tx,
shardID int32,View on GitHub (pinned to bde624efd1)
Solutions
- Query the shards table for the given shardID to see whether the row exists; delete duplicates if more than one.
- Check for triggers or modified schema affecting the shards table.
- Retry the operation; if the shard already exists, the normal read path (GetShard/ownership checks) will handle it.
- Verify driver and backend compatibility; test the same INSERT manually against the database.
Defensive patterns
Strategy: validation
Validate before calling
var n int
db.QueryRow("SELECT COUNT(*) FROM shards WHERE shard_id = ?", shardID).Scan(&n)
// n should be 0 before creation; n > 1 means duplicates already exist Try / catch
if strings.Contains(err.Error(), "shards instead of one") {
// inspect shards table for the shardID; repair duplicates, then retry
} Prevention
- Keep the shards schema (primary key on shard_id) unmodified from upstream.
- Avoid triggers on the shards table.
- Run one shard-creation owner per shard to prevent races.
When it happens
Trigger: Creating a shard where result.RowsAffected() returns 0 (row not actually inserted) or >1 (e.g., driver counting quirks).
Common situations: Replication setups reporting odd affected-row counts; triggers on the shards table; silent insert suppression from stale connections or unusual driver semantics.
Related errors
- rowsAffected returned error for shardID %v: %v
- rowsAffected returned error when initializing DLQ metadata
- error initializing cluster metadata manager: %w
- error while fetching cluster metadata: %w
- error while updating cluster metadata: %w
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/14369541d8c54181.
Report an issue: GitHub.