This is likely happening because the built-in subsasgn call for the struct probably just compares the output of fieldnames (which is dependent upon field order) for the source and destination structs and does not perform any sorting prior to the comparison (likely because of the performance hit of sorting two cell arrays for every assignment). If there is a difference (as in the case you've shown) then an error is thrown and the assignment is aborted.
The easiest way to get around this is to use orderfields on the source struct and specify that you want the ordering to match the destination struct's using the second input argument.
A = struct('x', 11, 'y', 12);
B = struct('y', 21, 'x', 22);
%// Ensure that the fields of B are in the same order as they are in A
A(1) = orderfields(B, A);
In my personal opinion, I think that subsasgn should do this itself for struct inputs because the operation is relatively fast (as there is no sorting and the underlying data of the struct isn't copied) but allows for more flexible struct assignment.
If, on the other hand you aren't doing direct assignment, but simply want to append two structs, the order of the fields does not matter and the order of the fields is inherited from the first struct that is encountered.
%// Uses the ordering of the fields in A
C = cat(1, A, B);
%// Uses the ordering of the fields in B
D = cat(1, B, A);
Update
I just noticed that you showed in your original post that the following worked because the order didn't matter.
A = B;
This works because this assignment is not dependent upon the datatype of A. In this scenario, MATLAB removes the data that A was referencing before the assignment and then re-assigns A it to the point to B. We could even make A a cell array and perform the above assignment with no issues.
A = cell(2);
B = struct('y', 21, 'x', 22);
%// No errors here!
A = B;
This assignment does not make a call to subsasgn (which deals only with subscript assignment) and therefore would not be expected to exhibit the issue you encountered.