Update field collection programatically - backend different to frontend
Well, as always happens I found the answer just after I posted the question:

// Unset and start afresh
unset($node-&gt;field_composition[LANGUAGE_NONE]);

foreach($fids as $fid){
  $comp = entity_load_single('field_collection_item', array($fid));
  $comp-&gt;field_chemical[LANGUAGE_NONE][0]['target_id'] = $id; // These values are derived elsewhere and are correct
  $comp-&gt;field_weight[LANGUAGE_NONE][0]['value'] = $value; // These values are derived elsewhere and are correct
  $comp-&gt;save(TRUE);
  $node-&gt;field_composition[LANGUAGE_NONE][] = array(
    'value' =&gt; $comp-&gt;item_id,
    'revision_id' =&gt; $comp-&gt;revision_id // ADDED REVISION ID HERE!
  );
}

node_save($node);