CommCare/OpenMRS integration error: KeyError: 'identifierType'

HI all,

At Partners In Health, we've had CommCare/OpenMRS integration working for a few years now for a CHW<-> Facility referral workflow.

In one of our test environments for this workflow, we are receiving this error when sending an encounter from CommCare to OpenMRS:

400: Bad Request. Errors: [ "SyncPatientIdentifiersTask.run() failed: KeyError: 'identifierType'" ]

We know that the integration user is authenticating successfully on OpenMRS but then we are getting this error/

We've made some OpenMRS changes that shouldn't have affected this workflow, but may have (hence, the test). We don't know what this error means so are kind of stuck in researching where the problem is.

We have a question in to CommCare support but so far we have not been able to escalate this to the correct resources to help us.

Has anyone seen this or have any thoughts on what this could be? Any help would be appreciated!

Thanks.
Dave

cc: @Norman_Hooper

Hi Dave,

The SyncPatientIdentifiersTask checks that the OpenMRS patient's identifiers match the data on the CommCare case that corresponds to that patient.

That error is happening because CommCare is unable to parse the patient identifier data. Something is missing; specifically the "identifierType", but probably other things too. "identifierType" is just the first missing property it encountered, so that's where it errored out.

Navigate to Remote API Logs, and select a GET request where CommCare fetches the details of a patient, to see an example of the patient JSON data that OpenMRS is sending to CommCare. Compare the response body to the following example of what CommCare thinks a patient identifier looks like:

  // ...
  "identifiers": [
    {
      "display": "National ID = 921126 1234 089",
      "identifierType": {
        "uuid": "cee12452-1c67-4a38-81d6-0ec6f1b751e9",
      },
      "uuid": "516ed116-cdc6-4a43-be77-3d67f03761ad",
      "identifier": "921126 1234 089"
    },
    {
      "display": "CHI Number = 2611921234",
      "identifierType": {
        "uuid": "82740171-04e6-45ab-a841-d7c3024b13cf",
      },
      "uuid": "69b21e47-7cd8-4e27-be61-6c1fb515faa3",
      "identifier": "2611921234"
    }
  ],
  // ...

If patient identifiers don't have those properties, CommCare will throw an error.

If this was working before, then I suspect that one of those changes resulted in a slightly different API response format.

Please let me know how you get on.

Thanks,

Norman

Hi Dave,

I have an update to your question. I ran a quick test against Bahmni's OpenMRS demo server -- I just registered a test patient. Here is what the "identifiers" block in OpenMRS's response looks like, when CommCare asks for the patient's details:

  // ...
  "identifiers": [
    {
      "display": "Patient Identifier = BAH203001",
      "identifier": "BAH203001",
      "identifierType": {
        "display": "Patient Identifier",
        "links": [
          {
            "rel": "self",
            "uri": "http://localhost:8050/openmrs/ws/rest/v1/patientidentifiertype/81433852-3f10-11e4-adec-0800271c1b75"
          }
        ],
        "uuid": "81433852-3f10-11e4-adec-0800271c1b75"
      },
      "links": [
        {
          "rel": "self",
          "uri": "http://localhost:8050/openmrs/ws/rest/v1/patient/9f4c5218-198c-413e-b3f0-2bbc036566c9/identifier/6d036cd9-1211-473c-94fd-6f19962a0fa1"
        },
        {
          "rel": "full",
          "uri": "http://localhost:8050/openmrs/ws/rest/v1/patient/9f4c5218-198c-413e-b3f0-2bbc036566c9/identifier/6d036cd9-1211-473c-94fd-6f19962a0fa1?v=full"
        }
      ],
      "location": null,
      "preferred": true,
      "resourceVersion": "1.8",
      "uuid": "6d036cd9-1211-473c-94fd-6f19962a0fa1",
      "voided": false
    }
  ],
  // ...

You can find the full response at this URL -- https://demo.mybahmni.org/openmrs/ws/rest/v1/patient/9f4c5218-198c-413e-b3f0-2bbc036566c9?v=full -- The credentials for the demo server are superman / Admin123 ( https://bahmni.atlassian.net/wiki/spaces/BAH/pages/61997323/Bahmni+Online+Demo ) I'm sure the demo server gets reset every 24 hours, so you may need to register another patient.

As you can see, that's a lot more detail in the response above than what would cause the error you are experiencing:

  // ...
  "identifiers": [
    {
      "display": "XY EMR ID = A1BCDE",
      "links": [
        {
          "rel": "self",
          "resourceAlias": "identifier",
          "uri": "https://example.org:443/openmrs/ws/rest/v1/patient/ee293e16-9560-4156-8ff4-43f3cfdbedaf/identifier/2d53cb49-688b-4175-8dba-ce704bf1246b"
        }
      ],
      "uuid": "2d53cb49-688b-4175-8dba-ce704bf1246b"
    }
  ],
  // ...

I strongly encourage you to dive into Project Settings > Remote API Logs in CommCare HQ. There you will see all details (except for credentials) of the requests that CommCare HQ sends, and the responses.

(As you will see from "Request params" in the logs, CommCare always requests full verbosity (v=full) when fetching patient details, so I don't think that can explain the difference between the response from the Bahmni demo server and the response you are getting.)

I hope that helps.

Norman

Hi @Norman_Hooper ,

Looking at the Remote API logs, it appears that the full verbosity parameter is being set as a part of the body in a JSON request. Is it safe to assume it does something like this?

GET /mirebalais/ws/rest/v1/patient/244286f7-ca8e-42f8-a185-51b8f1ca623e HTTP/1.1
Content-Type: application/json
{
	"v": "full"
}

Currently it looks like requests such as this on our systems do not end up getting the v=full parameter.

If I were to instead do this, things work as expected:

GET /mirebalais/ws/rest/v1/patient/244286f7-ca8e-42f8-a185-51b8f1ca623e?v=full HTTP/1.1

I'll investigate on our end, but interested if you have thoughts.

Thanks,
Mike

Hi @mseaton

I'm afraid it isn't obvious from the Remote API Logs UI what the URL ends up looking like.

Here is an example:

image

The request parameters are shown in a dictionary/hashmap so that they are easier to read, especially when there are a lot of them, like when you are passing multiple search filters and iterating paginated results, or when they include characters that would be encoded in a URL. But they are appended to the URL when the request is sent, as you would expect. So in this example, the URL will be https://demo.mybahmni.org/openmrs/ws/rest/v1/bahmni...?includeAll=true. The request headers will be Accept: application/json + basic auth credentials (which the log excludes), and the request body will be empty.

So, in your example, the URL will be the one that should work: .../mirebalais/ws/rest/v1/patient/244286f7-ca8e-42f8-a185-51b8f1ca623e?v=full.

If that URL is returning the full details of the patient when you test it, like the example from Bahmni's OpenMRS demo server, and not like the shorter details that leave out the "identifierType", then I wonder whether the difference has something to do with the credentials that CommCare is authenticating with. Do all API users get sent all patient details, or can some see more than others? What happens when you test using the same credentials that CommCare is using?

Hi @Norman_Hooper , thanks for your help on this!

@mseaton made some changes and we got it working today. I leave it to mike to explain if you are interested in the details, but I just wanted to let you know that we finally got it working.

Thanks!