Metadata API error while reading Picklist: Web service callout failed: Unable to find apex schema info
This is a very similar scenario to what is occurring in Tooling API in Apex - polymorphism, generic query() callout? and is caused by an underlying limitation in Wsdl2Apex and WebServiceCallout.invoke()
.
The Metadata API readMetadata
web method returns a generic ReadResult with records of type tns:Metadata
:
<xsd:complexType name="ReadResult">
<xsd:sequence>
<xsd:element name="records" minOccurs="0" maxOccurs="unbounded" type="tns:Metadata"/>
</xsd:sequence>
</xsd:complexType>
Which is fine, except in this case you don't get tns:Metadata
records back. You get tns:CustomField
records back that are an extension of tns:Metadata
and include a sequence of elements specific to custom fields.
WebServiceCallout.invoke
doesn't know how to unpack the specific CustomField complex type when it was just expecting Metadata.
Instead, you need to create a classes to do this and then utilize them in a dedicated version of the readMetadata method.
It looks like you are using the apex-mdapi implementation here for readMetadata. This attempts to overcome the limitation above by passing in target metadata type with the type_x
parameter and then adjusting the final infoArray
parameter on WebServiceCallout.invoke to have a response type that matches what will come back from the WebService.
This will be a readCustomFieldResponse_element
in your case and the corresponding ReadCustomFieldResult.
This is the point where I believe the issue is. Your CustomField needs to match that of your current API version. Each element that comes back needs to have a corresponding propertyName_type_info.
Taken from Issue # 225 on their repo. Error occurred when obtaining a custom picklist fields CustomValue
.
Error:
System.CalloutException: Web service callout failed: Unable to find apex schema info
Fresh install looked like this:
public virtual class CustomValue extends Metadata { public String color; public Boolean default_x; public String description; public Boolean isActive; public String label; }
Replacement code should look something like this (you can edit it as needed):
public virtual class CustomValue extends Metadata { public String type = 'CustomValue'; public String fullName; private String[] fullName_type_info = new String[]{'fullName',API_END,null,'0','1','false'}; public String color; public Boolean default_x; public String description; public Boolean isActive; public String label; private String[] color_type_info = new String[]{'color',API_END,null,'0','1','false'}; private String[] default_x_type_info = new String[]{'default',API_END,null,'1','1','false'}; private String[] description_type_info = new String[]{'description',API_END,null,'0','1','false'}; private String[] isActive_type_info = new String[]{'isActive',API_END,null,'0','1','false'}; private String[] label_type_info = new String[]{'label',API_END,null,'0','1','false'}; private String[] apex_schema_type_info = new String[]{API_END,'true','false'}; private String[] field_order_type_info = new String[]{'fullName','color','default_x','description','isActive','label'}; }
Steps:
- Replace the class
CustomValue
with the above code. - Replace
API_END
withSOAP_M_URI