Before changing recipes the crafting combinator removes items from the assembler. Which has the problem that inserter can fill it right back up when the chest is full and only part of the items can be removed every try.
Instead the combinator should should use the return value of assembler.set_recipe() to get the left over items out of the assembler, remember them in the crafting combinator and put them back into the chest as space allows.
The inserters modules could also be handled this way. Setting the new recipe will return the modules if needed. Simply check modules before and after setting the recipe and if they differ then the returned items include the modules and they can be put into the module chest.