# Fix "not supported on device" DeviceErrors in PennyLane

Use this when executing a QNode raises `pennylane.exceptions.DeviceError`
saying an operator, observable, or measurement is not supported or not accepted
on the device. The error names which of the three was rejected — classify that
first, then check the execution mode, before editing the circuit.

## 1. Read the error — it tells you which of three things is rejected

| Error pattern | What's rejected | Typical cause |
|---|---|---|
| `Operator X(wires=[...]) not supported on device and does not provide a decomposition.` (older versions: `Gate X not supported on device ...`) | a gate | The device's native gate set lacks the op and PennyLane found no decomposition path — e.g. `DeviceError: Gate RX not supported on device default.gaussian` |
| `Observable ... not supported on device` | an observable inside `qml.expval`/`qml.var` | The observable is outside the device's accepted set |
| `Measurement ... not accepted for analytic simulation on device.` | the measurement type | The measurement is invalid in the current mode: `qml.state()`/`qml.density_matrix()` on hardware (simulator-only measurements), or sample-based measurements with `shots=None` |

## 2. Classify, then check the mode

- **Op rejected**: CV devices (`default.gaussian`) support only Gaussian
  operations — use `qml.Rotation` instead of `qml.RX`, or move the circuit to
  `default.qubit`. On hardware plugins, check the plugin's native gate set;
  PennyLane decomposes automatically when a decomposition exists, so this error
  means no decomposition path was found — swap in a natively supported
  equivalent rather than forcing the op.
- **Observable rejected**: rewrite the observable from supported pieces
  (e.g. a `qml.Hamiltonian`/`qml.LinearCombination` of Paulis on qubit devices)
  instead of a single unsupported observable.
- **Measurement rejected**: `qml.state()` and `qml.density_matrix()` are
  simulator-only — on hardware or remote devices (e.g. Strawberry Fields
  remote) they are rejected outright; use `qml.expval`, `qml.probs`, or
  `qml.sample` instead. Sample-based measurements (`qml.sample`,
  `qml.counts`) need finite shots: `qml.device("default.qubit", wires=2,
  shots=1000)`. Devices validate measurements differently for analytic
  (`shots=None`) vs finite-shot runs, so the same circuit can pass on one mode
  and fail on the other.

## 3. Diagnose before editing

```python
import pennylane as qml

specs = qml.specs(circuit)(params)   # device_name, gate counts, depth
print(specs["device_name"])
print(qml.draw(circuit, wire_order=dev.wires)(params))
```

`qml.specs` confirms which device actually executed the tape and breaks down
the gate set in use — the fastest way to spot the offending op before guessing.

## 4. Checklist for the failing execution

1. Copy the exact DeviceError; identify op / observable / measurement from the
   table in step 1.
2. Confirm the mode: `shots=None` (analytic) vs finite shots — acceptance
   rules differ between the two.
3. Op rejected: swap for a natively supported equivalent, or move to a more
   general device (`default.qubit`).
4. Measurement rejected: `qml.state()` means simulator only; sampling means
   set `shots`.
5. Re-run `qml.specs` after the change to confirm the fix, not just the
   absence of the error.
