anchor.diff:          }
           break;
         case _AssetField.Id:
  -        return serializer._assetIdToId[node.id];
  +        return serializer.findAssetIndex(node.id, from: node.id, field: 'id');
         case _AssetField.Outputs:
           return node.outputs
  -            .map((id) => serializer._assetIdToId[id])
  +            .map((id) =>
  +                serializer.findAssetIndex(id, from: node.id, field: 'outputs'))
               .toList(growable: false);
         case _AssetField.PrimaryOutputs:
           return node.primaryOutputs
  -            .map((id) => serializer._assetIdToId[id])
  +            .map((id) => serializer.findAssetIndex(id,
  +                from: node.id, field: 'primaryOutputs'))
               .toList(growable: false);
         case _AssetField.Digest:
           return _serializeDigest(node.lastKnownDigest);
         case _AssetField.DeletedBy:
           return node.deletedBy
  -            .map((id) => serializer._assetIdToId[id])
  +            .map((id) => serializer.findAssetIndex(id,
  +                from: node.id, field: 'deletedBy'))
               .toList(growable: false);
         default:
           throw RangeError.index(index, this);
  
positive.code:     switch (fieldId) {
        case _GeneratedField.PrimaryInput:
          return generatedNode.primaryInput != null
              ? serializer._assetIdToId[generatedNode.primaryInput]
              : null;
        case _GeneratedField.WasOutput:
          return _serializeBool(generatedNode.wasOutput);
  
negative.code:       case _GeneratedField.PreviousInputsDigest:
          return _serializeDigest(generatedNode.previousInputsDigest);
        case _GeneratedField.BuilderOptions:
          return serializer.findAssetIndex(generatedNode.builderOptionsId,
              from: generatedNode.id, field: 'builderOptions');
        case _GeneratedField.IsHidden:
          return _serializeBool(generatedNode.isHidden);
        default:
  