# Buggy code
def _matrix(cls, *params):
    theta = params[0]
    pauli_word = params[1]

    if not PauliRot._check_pauli_word(pauli_word):
        raise ValueError(
            'The given Pauli word "{}" contains characters that are not allowed.'
            " Allowed characters are I, X, Y and Z".format(pauli_word)
        )

    # We first generate the matrix excluding the identity parts and expand it afterwards.
    # To this end, we have to store on which wires the non-identity parts act
    non_identity_wires, non_identity_gates = zip(
        *[(wire, gate) for wire, gate in enumerate(pauli_word) if gate != "I"]
    )

    multi_Z_rot_matrix = MultiRZ._matrix(theta, len(non_identity_gates))

    # now we conjugate with Hadamard and RX to create the Pauli string
    conjugation_matrix = functools.reduce(
        np.kron,
        [PauliRot._PAULI_CONJUGATION_MATRICES[gate] for gate in non_identity_gates],
    )

    return expand(
        conjugation_matrix.T.conj() @ multi_Z_rot_matrix @ conjugation_matrix,
        non_identity_wires,
        list(range(len(pauli_word))),
    )


# Traceback (ValueError)
----------------------------------------------------
ValueError         Traceback (most recent call last)
<ipython-input-27-611f77c1af9c> in <module>
12     return qml.expval(qml.PauliX(1))
13
---> 14 print(apply_pauli_rots(0.345))

~/Software/anaconda3/envs/test-xanadu/lib/python3.8/site-packages/pennylane/interfaces/autograd.py in __call__(self, *args, **kwargs)
67             self.set_trainable(args)
68             args = autograd.builtins.tuple(args)  # pylint: disable=no-member
---> 69             return self.evaluate(args, kwargs)
70
71         @staticmethod

~/Software/anaconda3/envs/test-xanadu/lib/python3.8/site-packages/autograd/tracer.py in f_wrapped(*args, **kwargs)
46             return new_box(ans, trace, node)
47         else:
---> 48             return f_raw(*args, **kwargs)
49     f_wrapped.fun = f_raw
50     f_wrapped._is_autograd_primitive = True

~/Software/anaconda3/envs/test-xanadu/lib/python3.8/site-packages/pennylane/qnodes/base.py in evaluate(self, args, kwargs)
817
818         if self.circuit is None or self.mutable:
--> 819             self._construct(args, kwargs)
820
821         self.device.reset()

~/Software/anaconda3/envs/test-xanadu/lib/python3.8/site-packages/pennylane/qnodes/jacobian.py in _construct(self, args, kwargs)
87         for each positional parameter.
88         """
---> 89         super()._construct(args, kwargs)
90         self.par_to_grad_method = {k: self._best_method(k) for k in self.variable_deps}
91

~/Software/anaconda3/envs/test-xanadu/lib/python3.8/site-packages/pennylane/qnodes/base.py in _construct(self, args, kwargs)
574
575         # check the validity of the circuit
--> 576         self._check_circuit(res)
577         del self.queue
578         del self.obs_queue

~/Software/anaconda3/envs/test-xanadu/lib/python3.8/site-packages/pennylane/qnodes/base.py in _check_circuit(self, res)
731         if self.device.operations:
732             # replace operations in the queue with any decompositions if required
--> 733             queue = decompose_queue(self.queue, self.device)
734
735         self.ops = queue + list(res)

~/Software/anaconda3/envs/test-xanadu/lib/python3.8/site-packages/pennylane/qnodes/base.py in decompose_queue(ops, device)
123     for op in ops:
124         try:
--> 125             new_ops.extend(_decompose_queue([op], device))
126         except NotImplementedError:
127             raise qml.DeviceError(

~/Software/anaconda3/envs/test-xanadu/lib/python3.8/site-packages/pennylane/qnodes/base.py in _decompose_queue(ops, device)
98             new_ops.append(op)
99         else:
--> 100             decomposed_ops = op.decomposition(*op.data, wires=op.wires)
101             if op.inverse:
102                 decomposed_ops = qml.inv(decomposed_ops)

~/Software/anaconda3/envs/test-xanadu/lib/python3.8/site-packages/pennylane/templates/decorator.py in wrapper(*args, **kwargs)
59     def wrapper(*args, **kwargs):
60         with OperationRecorder() as rec:
---> 61             func(*args, **kwargs)
62
63         return rec.queue

~/Software/anaconda3/envs/test-xanadu/lib/python3.8/site-packages/pennylane/ops/qubit.py in decomposition(theta, pauli_word, wires)
925     @template
926     def decomposition(theta, pauli_word, wires):
--> 927         active_wires, active_gates = zip(
928             *[(wire, gate) for wire, gate in zip(wires, pauli_word) if gate != "I"]
929         )

ValueError: not enough values to unpack (expected 2, got 0)

# Fixed code
def _matrix(cls, *params):
    theta = params[0]
    pauli_word = params[1]

    if not PauliRot._check_pauli_word(pauli_word):
        raise ValueError(
            'The given Pauli word "{}" contains characters that are not allowed.'
            " Allowed characters are I, X, Y and Z".format(pauli_word)
        )

    # Simplest case is if the Pauli is the identity matrix
    if pauli_word == "I" * len(pauli_word):
        return np.exp(-1j * theta / 2) * np.eye(2 ** len(pauli_word))

    # We first generate the matrix excluding the identity parts and expand it afterwards.
    # To this end, we have to store on which wires the non-identity parts act
    non_identity_wires, non_identity_gates = zip(
        *[(wire, gate) for wire, gate in enumerate(pauli_word) if gate != "I"]
    )

    multi_Z_rot_matrix = MultiRZ._matrix(theta, len(non_identity_gates))

    # now we conjugate with Hadamard and RX to create the Pauli string
    conjugation_matrix = functools.reduce(
        np.kron,
        [PauliRot._PAULI_CONJUGATION_MATRICES[gate] for gate in non_identity_gates],
    )

    return expand(
        conjugation_matrix.T.conj() @ multi_Z_rot_matrix @ conjugation_matrix,
        non_identity_wires,
        list(range(len(pauli_word))),
    )