Q:

WSO2 API Manager Converting JSON to XML (and failing the request)

We are using the WSO2 API manager as an API Gateway.  One of the APIs I have is a JSON-only not-fully-restful API.  It uses HTTP POST requests with JSON as a data exchange format.  I have a very basic configuration for this: Configured as a REST API with POST /* allowed.
Some of the responses include JSON which has strings like "P~A" as object keys.  When I try to call this via the gateway it chokes on the response:
2018-09-13 18:37:37,890 [-] [PassThroughMessageProcessor-36] ERROR JsonUtil #writeAsJson. Could not convert OMElement to JSON. Invalid XML payload. Error>>> Unexpected character '~' (code 126) excepted space, or '>' or "/>"
 at [row,col {unknown-source}]: [1,4956]
2018-09-13 18:37:37,891 [-] [PassThroughMessageProcessor-36] ERROR PassThroughHttpSSLSender Failed to submit the response
org.apache.axis2.AxisFault: Could not convert OMElement to JSON. Invalid XML payload.
        at org.apache.synapse.commons.json.JsonUtil.writeAsJson(JsonUtil.java:372)
        at org.apache.synapse.commons.json.JsonFormatter.writeTo(JsonFormatter.java:84)
        at org.apache.synapse.transport.passthru.PassThroughHttpSender.submitResponse(PassThroughHttpSender.java:573)
        at org.apache.synapse.transport.passthru.PassThroughHttpSender.invoke(PassThroughHttpSender.java:264)
        at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:442)
        at org.apache.synapse.core.axis2.Axis2Sender.sendBack(Axis2Sender.java:230)
        at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.send(Axis2SynapseEnvironment.java:531)
        at org.apache.synapse.mediators.builtin.SendMediator.mediate(SendMediator.java:118)
        at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:97)
        at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:59)
        at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:158)
        at org.apache.synapse.rest.Resource.process(Resource.java:343)
        at org.apache.synapse.rest.API.process(API.java:338)
        at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:90)
        at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:56)
        at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:304)
        at org.apache.synapse.core.axis2.SynapseCallbackReceiver.handleMessage(SynapseCallbackReceiver.java:554)
        at org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackReceiver.java:188)
        at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
        at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:262)
        at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Caused by: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '~' (code 126) excepted space, or '>' or "/>"
 at [row,col {unknown-source}]: [1,4956]
        at com.ctc.wstx.sr.StreamScanner.throwUnexpectedChar(StreamScanner.java:647)
        at com.ctc.wstx.sr.BasicStreamReader.handleNsAttrs(BasicStreamReader.java:2996)
        at com.ctc.wstx.sr.BasicStreamReader.handleStartElem(BasicStreamReader.java:2963)
        at com.ctc.wstx.sr.BasicStreamReader.nextFromTree(BasicStreamReader.java:2839)
        at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1073)
        at javax.xml.stream.util.StreamReaderDelegate.next(Unknown Source)
        at javax.xml.stream.util.StreamReaderDelegate.next(Unknown Source)
        at org.codehaus.stax2.ri.Stax2ReaderAdapter.next(Stax2ReaderAdapter.java:129)
        at org.codehaus.stax2.ri.Stax2EventReaderImpl.peek(Stax2EventReaderImpl.java:367)
        at org.apache.synapse.commons.staxon.core.event.SimpleXMLEventWriter.add(SimpleXMLEventWriter.java:118)
        at org.apache.synapse.commons.json.JsonUtil.writeAsJson(JsonUtil.java:368)
        ... 23 more
2018-09-13 18:37:37,892 [-] [PassThroughMessageProcessor-36] ERROR Axis2Sender Access-Control-Allow-Headers:authorization,Access-Control-Allow-Origin,Content-Type,SOAPAction,Access-Control-Allow-Methods:HEAD,DELETE,POST,PATCH,PUT,GET,Access-Control-Allow-Origin:*,Content-Type:application/json;charset=utf-8,<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><jsonObject>

(it then continues and includes XML which tries to use the "P~A" keys from the JSON as <P~A> XML tags, which is what it chokes on)
The API definition does not have message mediate enabled and also has response caching disabled.  So, I'm not clear why it's even using the mediator and trying to convert my JSON response to XML at all.
So, the question: how to get this working?  Either by configuring it to cope with converting that to XML or not need to?
I would also note that something in this process takes a long time.  It takes a very long time before I get the (error) response but I see that the response data arrives in the API manager quickly.
We do also have the WSO2 Analytics service running.  I tried stopping that in case it was causing the issue.  Didn't help

A:

I'm posting this as an answer because it solves the problem.  Add 
synapse.commons.json.buildValidNCNames=true

To the repository/conf/synapse.properties file.
It makes it cope with the ~ (and anything else not valid in a tag) using character codes.
I guess maybe the mediation isn't the message mediation (which was disabled) but something more internal.  In that case I really don't understand why the above setting isn't the default value - I don't see a downside with it and without it, the gateway can't cope with certain JSON!

