As you say, the resultant types at either end of the noodle match, (or can be cast to one another). But there is a distinction between Fields, marked by diamond sockets, and regular data, marked by circular sockets.
Fields are function-calls, returning the results of attribute look-ups and interpolations, and other calculations in the tree, in which the target geometry is a parameter. So a Field, for example, will return a different Position value for every vertex in the target geometry, and interpolate for points in between them.
At the point of creation, a Curve Primitive > Circle, is a single entity. It has only one radius, which is set directly via a variable, not a function-call. The base-radius can be set via a single float in the interface.
If, then, for example, you instance your circle on the points of a grid, all the instances share the creation-data. The data can not be varied per-circle, until the instances are realised. But the circle-instances do each carry their own transform. The instances can be scaled, rotated and translated independently, just as instances can outside GN, in Object Mode.
The blue nodes in this tree show the instances (not the primitive) being scaled, by a function of vertex-weights, when generated per-point of a grid:

Here's the modified grid, showing its vertex-weights, and the result:

The instances do not have the vertex-weights as an attribute themselves. If, say, you want to translate the instances by the grid's vertex-weights, you have to transfer the weights from the grid to the instances, possibly as shown by the green nodes, above. Here the transfer can be made with the Index as key, because at this stage, the instances have the same Index as the vertices they were created on.
