apache/shardingsphere · error · AlgorithmInitializationException

Weight `%s` of available target `%s` should be number.

Error message

Weight `%s` of available target `%s` should be number.

What it means

AlgorithmInitializationException thrown by WeightLoadBalanceAlgorithm.init when a configured weight property cannot be parsed as a number: Double.parseDouble(weight) raises NumberFormatException and the init fails naming the offending weight and target. Every property key in the algorithm props is treated as a target name whose value must be a numeric weight.

Source

Thrown at infra/algorithm/type/load-balancer/type/weight/src/main/java/org/apache/shardingsphere/infra/algorithm/loadbalancer/weight/WeightLoadBalanceAlgorithm.java:56

public final class WeightLoadBalanceAlgorithm implements LoadBalanceAlgorithm {
    
    private static final double ACCURACY_THRESHOLD = 0.0001;
    
    private final Map<String, double[]> weightMap = new ConcurrentHashMap<>();
    
    private final Map<String, Double> weightConfigMap = new HashMap<>();
    
    @Override
    public void init(final Properties props) {
        Collection<String> availableTargetNames = props.stringPropertyNames();
        ShardingSpherePreconditions.checkNotEmpty(availableTargetNames, () -> new AlgorithmInitializationException(this, "Available target is required."));
        for (String each : availableTargetNames) {
            String weight = props.getProperty(each);
            ShardingSpherePreconditions.checkNotNull(weight, () -> new AlgorithmInitializationException(this, "Weight of available target `%s` is required.", each));
            try {
                weightConfigMap.put(each, Double.parseDouble(weight));
            } catch (final NumberFormatException ex) {
                throw new AlgorithmInitializationException(this, "Weight `%s` of available target `%s` should be number.", weight, each);
            }
        }
    }
    
    @Override
    public void check(final String databaseName, final Collection<String> configuredTargetNames) {
        weightConfigMap.keySet().forEach(each -> ShardingSpherePreconditions.checkContains(configuredTargetNames, each,
                () -> new AlgorithmInitializationException(this, "Target `%s` is required in database `%s`.", each, databaseName)));
        configuredTargetNames.forEach(each -> ShardingSpherePreconditions.checkContains(weightConfigMap.keySet(), each,
                () -> new AlgorithmInitializationException(this, "Weight of target `%s` is required in database `%s`.", each, databaseName)));
    }
    
    @HighFrequencyInvocation
    @Override
    public String getTargetName(final String groupName, final List<String> availableTargetNames) {
        double[] weight = weightMap.containsKey(groupName) && weightMap.get(groupName).length == availableTargetNames.size() ? weightMap.get(groupName) : initWeight(availableTargetNames);
        weightMap.put(groupName, weight);
        return getAvailableTargetName(availableTargetNames, weight);

View on GitHub (pinned to e952770a21)

Solutions

  1. Correct the weight values to plain numbers ('1', '2.5') for every target.
  2. Remove any non-target properties from this algorithm's props; the weight algorithm accepts only target-name -> weight entries.
  3. Verify every configured replica/read-write-splitting target has its own numeric weight entry (the check() method enforces both directions).

Example fix

# before
algorithm:
  type: WEIGHT
  props:
    read_ds_0: 70%
    read_ds_1: 0.3x

# after
algorithm:
  type: WEIGHT
  props:
    read_ds_0: '70'
    read_ds_1: '30'
Defensive patterns

Strategy: validation

Validate before calling

// Validate weight props before building the algorithm
for (Map.Entry<String, String> e : weightProps.entrySet()) {
    try {
        Double.parseDouble(e.getValue());
    } catch (NumberFormatException ex) {
        throw new IllegalArgumentException("Weight for " + e.getKey() + " must be numeric: " + e.getValue());
    }
}

Type guard

boolean isNumericWeight(final String value) {
    return value != null && value.matches("-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?");
}

Try / catch

try {
    algorithm.init(props);
} catch (final AlgorithmInitializationException ex) {
    // message names the bad weight; fix config and re-init — do not continue with partial weights
}

Prevention

When it happens

Trigger: Configuring the weight load balancer with a non-numeric weight, e.g. props { 'ds_0': '1', 'ds_1': 'abc' } or '0.5x', or accidentally including a non-weight property key (whose value is non-numeric) in the algorithm properties.

Common situations: YAML/DistSQL typos in weight values; units or percent signs left in values ('70%'); mixed-in unrelated algorithm properties because the weight algorithm treats every property key as a target.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/eb7c04e6025a37d3. Report an issue: GitHub.