Question

REST API call from FME HTTPCaller gives an error of "HTTP/2 400" but from Postman it works fine

  • 25 April 2024
  • 7 replies
  • 83 views

Badge +1

Hi All, 

I have FME Form 2023.2.

I am trying to make a REST API call using HTTPCaller. I got this error below,

{
    "code": "data_validation_error",
    "message": "Invalid request values. Unexpected character ('_' (code 95)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')",
    "status": 400,
    "traceId": "240425163408767-2c15ec9a"
}

However, the same request works just fine on Postman. Not sure what exactly the error means here. Can anyone help me on this?

Here is the HTTPCaller screenshot.

Here is the request body,

 

Here is the error messages from the Translation log.

##########

...

UpdateRecordCustomTablesHTTPCaller (HTTPFactory): An error occurred while accessing the URL 'https://apis.accela.com/v4/records/PINELLAS-24CAP-00000-0004H/customTables'
The below feature caused the translation to be terminated
Storing feature(s) to FME feature store file `C:\FME\Funeral Home\FuneralHomeBillingInterfacefmw_log.ffs'
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `FEATURE_TYPE'
Attribute(string: UTF-8)          : `ApprovalDate' has value `2021-12-29'
Attribute(32 bit unsigned integer): `CACNumber' has value `2118566'
Attribute(string: windows-1252)   : `DeceasedFirstName' has value `xxx'
Attribute(string: windows-1252)   : `DeceasedLastName' has value `xxx'
Attribute(string: windows-1252)   : `DeceasedMiddleInitial' has value `xxx'
Attribute(string: windows-1252)   : `FHIdentifier' has value `F040344'
Attribute(string: UTF-8)          : `RecordId' has value `PINELLAS-24CAP-00000-0004H'
Attribute(string: UTF-8)          : `_RecordCustomTablesJson' has value `[ { "id" : "HS_CREMATION-GENERAL.cINFORMATION", "rows" : [ { "action" : "add", "fields" : { "Cremation Approval Number" : "2118566", "Cremation Date" : "2021-12-29", "First Name" : "xxx", "Middle Name" : "xxx", "Last Name" : "xxx" }, "id" : 1 } ] } ]'
Attribute(string: UTF-8)          : `_error' has value `HTTP/2 400'
Attribute(16 bit unsigned integer): `_http_status_code' has value `400'
Attribute(string: UTF-8)          : `_response_body' has value `{"status":400,"code":"data_validation_error","message":"Invalid request values. Unexpected character ('_' (code 95)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')","traceId":"240425215017149-42dfe79c"}'
Attribute(string; UTF-8)          : `fme_feature_type' has value `CSV'
Attribute(string: US-ASCII)       : `fme_geometry' has value `fme_undefined'
Attribute(string; UTF-8)          : `fme_rejection_code' has value `NO_RESULT'
Attribute(string: US-ASCII)       : `fme_type' has value `fme_no_geom'
Coordinate System: `'
Geometry Type: IFMENull
Coordinate Dimension: 2
===========================================================================
UpdateRecordCustomTablesHTTPCaller_<Rejected> (TeeFactory): UpdateRecordCustomTablesHTTPCaller_<Rejected>: Termination Message: 'UpdateRecordCustomTablesHTTPCaller output a <Rejected> feature.  To continue translation when features are rejected, change 'Workspace Parameters' > Translation > 'Rejected Feature Handling' to 'Continue Translation''
Translation FAILED with 3 error(s) and 0 warning(s) (0 feature(s) output)

############

Here is the screenshot on Postman.

 

Thanks,

-John


7 replies

Userlevel 6
Badge +33

Do you have the same headers in Postman? What happens if you remove Accept from the headers?

Badge +1

Thanks, nielsgerrits 

With your hint, I have some new findings. 

I played the Headers on Postman. Here are the least settings I can have to make a successful call on Postman. All I need are three attributes, Authentication, Content-Length and Host.

 

If I removed the attribute Content-Length, I got this error,

{

    "status": 400,

    "code": "bad_request",

    "message": "Request body is required.",

    "traceId": "240426143249919-6eda4c52"

}

If I removed the attribute Host, I got this error,

<!DOCTYPE html

    PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>

<html xmlns='http://www.w3.org/1999/xhtml'>

<head>

    <meta content='text/html; charset=utf-8' http-equiv='content-type' />

    <style type='text/css'>

        body {

            font-family: Arial;

            margin-left: 40px;

        }

        img {

            border: 0 none;

        }

        #content {

            margin-left: auto;

            margin-right: auto

        }

        #message h2 {

            font-size: 20px;

            font-weight: normal;

            color: #000000;

            margin: 34px 0px 0px 0px

        }

        #message p {

            font-size: 13px;

            color: #000000;

            margin: 7px 0px 0px0px

        }

        #errorref {

            font-size: 11px;

            color: #737373;

            margin-top: 41px

        }

    </style>

    <title>Service unavailable</title>

</head>

<body>

    <div id='content'>

        <div id='message'>

            <h2>Our services aren't available right now</h2>

            <p>We're working to restore all services as soon as possible. Please check back soon.</p>

        </div>

        <div id='errorref'>

            <span>            </span>

        </div>

    </div>

</body>

</html>

So on FME, just follow what I have on Postman, I only set three same Headers attributes, Authentication, Content-length and Host. I found what the values of Content-length and Host are from Postman Console. 

Content-Length = 550

Host = “apis.accela.com”

When I run it, it gave me a different error of HTTP/2 421 this time. The response body is the same as one of two scenarios above where I removed the attribute Host from the Headers on Postman. It seems to me the Attribute Host on FME doesn’t make any difference as it does on Postman. is there a way we can look into the whole request Headers, the Headers which is sent out,  on FME? 

 

Thanks,

 

-John

Badge +1

I posted a reply a few minutes early this morning. Somehow it didn’t show up. Let me try again.

First, to your question. If I removed the Headers attribute, I got the same error.

With your hint, I played a little bit more on Postman and have some new foundlings. Here is the least Headers settings I have to make a successful call on Postman. All I need are three attributes, Authentication, Content-length and Host. 

When I removed the attribute Content-type, I got this error,

{

    "status": 400,

    "code": "bad_request",

    "message": "Request body is required.",

    "traceId": "240426150945036-c8dc66b8"

}

When I removed the attribute Host, I got this HTML response back.

<!DOCTYPE html

    PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>

<html xmlns='http://www.w3.org/1999/xhtml'>

<head>

    <meta content='text/html; charset=utf-8' http-equiv='content-type' />

    <style type='text/css'>

        body {

            font-family: Arial;

            margin-left: 40px;

        }

        img {

            border: 0 none;

        }

        #content {

            margin-left: auto;

            margin-right: auto

        }

        #message h2 {

            font-size: 20px;

            font-weight: normal;

            color: #000000;

            margin: 34px 0px 0px 0px

        }

        #message p {

            font-size: 13px;

            color: #000000;

            margin: 7px 0px 0px0px

        }

        #errorref {

            font-size: 11px;

            color: #737373;

            margin-top: 41px

        }

    </style>

    <title>Service unavailable</title>

</head>

<body>

    <div id='content'>

        <div id='message'>

            <h2>Our services aren't available right now</h2>

            <p>We're working to restore all services as soon as possible. Please check back soon.</p>

        </div>

        <div id='errorref'>

            <span>            </span>

        </div>

    </div>

</body>

</html>

Now I follow the same on FME. I only set up three Headers attributes Authentication, Content-Length and Host. I found what the values of Content-Length and Host are from the Postman Console.

Content-Length = 490

Host = apis.accela.com

When I run it on FME, I got the same error as the scenario above where I removed the Headers attribute Host on Postman. it seems that the Headers attribute Host doesn’t have any effect on FME as it does on Postman. Is there a way I can look into exactly what the Headers attribute on Post man when it sends the request out?

 

Thanks,

 

-John 

Badge +12

There is a way to show in postman what the exact call with headers etc is. Right arround the button where you make the call there should be something like this </> that shows the code. I didn't find something similar in FME.

I do read that your postman call return 200 but the message also indicates it is an error?

Did you verify that the number and id in your request body should be strings?

Sometimes I put Content-Type directly in the header as well

Badge +12

@missp29  it’s indeed the </> sign in postman that gives you how the call exactly looks like.

This is the example from the data you provided in FME

 

I see this from what you mention in postman:

 

The difference is at the end:

in your FME call it’s “id”: 1  → this 1 is an integer

in your postman call it’s “id”: “1” → this 1 is a string

 

So your issue might also be related with this

Badge +1

@tva Thank you very much for your help. 

If you see my original screenshots on FME, in one of template data, I did use “id”: “1”. I don’t data available right now. I will test again with both Integer and String once I have data available. I will let you know soon.

Thanks,

-John

Badge +12

Hi @missp29 ,

Once you have data again, lets go back to the initial structure that worked in postman and show us also the code result (the </> button).

Then show us what it is in FME you did with a view on all headers that you added and the exact json body.

And then we can take it from there again 😉

Reply