It is the simple things, or at least ones you assume must be simple that often create some extra anxiety with SharePoint – at least from what I’ve seen. Here is one I ran into a couple of days ago: my customer runs a SharePoint 2007 publishing portal with February 2010 CU, where content is created in authoring environment, then content deployment job transfers it to production farm located in perimeter zone and accessible to anonymous Internet users. The application is using a significant amount of custom code. In many cases SharePoint API is used as a data provider, and is accessed through an adapter layer, which helps decoupling custom code from the platform. Quite logical.
An example of how the adapter accesses SharePoint API is retrieving SharePoint document library information through SPList.GetItems(SPQuery).GetDataTable(). The DataTable instance is then returned back to the consuming custom code. The problem is that Modified column is missing from the returned DataTable in production farm, while it is there in authoring farm, which certainly breaks a lot of application logic.
It turns out that a Content Deployment Job Path setting (Central Administration > Operations > Manage Content Deployment Paths and Jobs > Content Deployment Path) is to blame: Security Information must be set to All in order for the issue to go away, and you would need to re-create the target site collection. Now this will not be a completely painless move – you will start getting a content deployment warning: User security information cannot be properly imported without setting UserInfoDateTime option to ImportAll. This is because you have a Deploy User Names checkbox cleared, which you should according to the guidance. Here is a related post about this warning.
What actually happens is when Security Information is not set to All, this results in hiding certain fields, including Modified date field. So the GetItems(SPQuery) will still return correct items satisfying the SPQuery parameter, but if you inspect properties of an SPField for the returned items you will see that:
item.Fields["Modified"].CanToggleHidden == false;
item.Fields["Modified"].Hidden == true;
and the SPListItemCollection.GetDataTable() method omits hidden fields when it constructs the DataTable. Knowing the above you can either edit content deployment path and do a clean content deployment, or if it is problematic for some reason, then you can change your custom code to manually construct a DataTable rather than using SPListItemCollection.GetDataTable().
UPDATE: The issue was fixed in April Cumulative Update (see http://support.microsoft.com/kb/981040/ for more details). Thanks to Bill Brockbank for noting this. A good moment to emphasize importance of running up-to-date software.