def check_charge_balance(model, r_id, tol=1e-6):
    """ Check charge balance of a reaction in a model.

    Notes:
        Since some metabolites can have multiple charges associated, it will check if at least one possible
        combination of all charges results in a balanced reaction.

    Args:
        model (CBModel): metabolic model
        r_id (str): reaction id
        tol (float): absolute tolerance to consider the charge to be balanced (default: 1e-6)

    Returns:
        bool: balance status (False if unbalanced or unable to calculate)
        str: error message (if reaction is not balanced)

    """

    reaction = model.reactions[r_id]
    combinations = [0]
    error = None

    for m_id, coeff in reaction.stoichiometry.items():
        metabolite = model.metabolites[m_id]
        if 'CHARGE' in metabolite.metadata:
            charges = metabolite.metadata['CHARGE'].split(';')
            combinations = [combination + int(charge)*coeff
                            for charge in charges
                            for combination in combinations]
        else:
            error = 'missing charge'
            break

    if error:
        return False, error

    balanced = [balance for balance in combinations if abs(balance) < tol]

    if len(balanced) >= 1:  # at least one combination must be valid
        return True, None
    else:
        return False, 'unbalanced'