No, it wasn't a typo but something rather fundamental. When you create a 3D object, the defaults are axis = vec(1,0,0) and up = vec(0,1,0), so axis and up start out being orthogonal. Then the attributes of this particular object are applied one after another, and setting axis also moves up to still be orthogonal to axis, and setting up also moves axis to still be orthogonal to up. The functions to do this were well tested.
What I had failed to test was your case, of cloning an object and changing its axis. Cloning of an object is done by calling the constructor with all arguments of the original object (pos, axis, size, up, etc.). Alas, that meant that axis and up were starting not from the standard values (<1,0,0> and <0,1,0>) but from whatever the to-be-cloned object's axis and up were, for which the axis-up orthogonalization functions failed.
The solution was not to specify up in creating the new object, so that setting axis would create an orthogonal up but there would be no modification of axis by up. Then after the clone is created, the new up is applied.