Retrieving and deploying namespaced layouts in Salesforce
Oli Lane on December 14th 2016
TL;DR: Retrieving namespaced layouts from Salesforce doesn't act quite as you might expect. Gearset now works around this quirk, so that you don't have to think about it.
Recently we received a slightly odd bug report from a user who claimed that Gearset was failing to include layouts inside namespaces in comparisons, despite the fact they had selected the Include managed packages option in the comparison filter. To add to the intrigue, the user was able to retrieve a list of the layouts using ANT, via a call to
listMetadata() - this is exactly what Gearset does as its first step, so it was surprising that the layouts weren't showing up.
We dug a little more into the issue, and found that we were able to see the layouts being retrieved correctly via the
listMetadata() call, but when the
retrieve() request went up to Salesforce, the layouts were never returned - very strange indeed.
Our user came to the rescue with some more research, and found the source of the issue: the layout name returned by the
listMetadata() call is subtly different to the name required to actually retrieve the layout. For example, Salesforce might return us a name like:
foo__BarBaz__c-Bar Baz Layout
but it will only return the layout when asked for:
foo__BarBaz__c-foo__Bar Baz Layout
Spot the difference? To retrieve the layout we need to make a request of the format
<Namespace>__<Object name>-<Namespace>__<Layout name>. However, the name returned by
listMetadata() is missing the second namespace prefix. In this case, to actually retrieve the layout, we need to insert an extra
foo__ into the name Salesforce returned.
We inserted some extra logic into Gearset's metadata retrieval strategy to fix up the names as it went along, and tested it out - lo and behold, hundreds of extra layouts suddenly appeared in our comparison.
This was a very strange edge case, and just goes to show that even in battle-tested software like Salesforce you can still find the occasional wrinkle! Many thanks to our brilliant user Lachlan Wetherall from CSA, who went above and beyond by researching this problem thoroughly and providing us with access to a test environment to reproduce the problem.