Valid JSON can still have the wrong type
If your request contains "address":"{...}", the address is a string containing JSON text. If the API expects "address":{...}, it needs an object. Both outer documents can be valid JSON, but they have different structures.
The fix is to use the intended type at the point where the value is inserted. Do not remove quotation marks or backslashes with text substitutions; that can damage legitimate string content.
Build the same address two ways
First construct a small object. This example uses fictional data and writes no records.
FileMaker script · compare nesting types
Set Variable [ $address ; Value: JSONSetElement ( "{}" ;
[ "city" ; "Da Nang" ; JSONString ] ;
[ "postalCode" ; "00042" ; JSONString ] ) ]
Set Variable [ $asText ; Value: JSONSetElement ( "{}" ;
"address" ; $address ; JSONString ) ]
Set Variable [ $asObject ; Value: JSONSetElement ( "{}" ;
"address" ; $address ; JSONObject ) ]Expected JSON structures · key order may differ
{"address":"{\"city\":\"Da Nang\",\"postalCode\":\"00042\"}"}
{"address":{"city":"Da Nang","postalCode":"00042"}}The first calculation deliberately serializes the address into a string. The second inserts an object. Keep postalCode as a string in both: nesting the object correctly is not a reason to turn its text identifiers into numbers.
Check the type, not the punctuation
FileMaker calculation
JSONGetElementType ( $asText ; "address" )
// Expected: JSONString (1)
JSONGetElementType ( $asObject ; "address" )
// Expected: JSONObject (3)These are two separate Data Viewer calculations; the comments describe expected results. Check the root type as well when accepting a payload from elsewhere. A JSON array is not an object, even if both are valid inputs to a formatter.
FileMaker script · require an object before nesting
Set Variable [ $input ; Value: $address ]
If [ JSONGetElementType ( $input ; "" ) ≠ JSONObject ]
Exit Script [ Text Result: "expected_address_object" ]
End If
Set Variable [ $body ; Value: JSONSetElement ( "{}" ;
"address" ; $input ; JSONObject ) ]
If [ JSONGetElementType ( $body ; "address" ) ≠ JSONObject ]
Exit Script [ Text Result: "invalid_nested_result" ]
End If
Exit Script [ Text Result: $body ]Claris documents the returned type constants in JSONGetElementType. Also validate the provider’s required keys and their types; an empty object passes the root-type check but may still be an invalid address.
Do not use JSONRaw as a repair button
JSONRaw asks FileMaker to interpret the supplied JSON value. It can fall back to a string for invalid JSON and can ignore trailing material after the first element. That behavior is unsuitable as a blanket “make this correct” step. Use a known object or array type and validate the input contract. See JSONSetElement’s type rules.
If an upstream service intentionally gives you a JSON string containing serialized JSON, unpack it only at that documented boundary, validate the decoded structure, and then insert it with the correct type. Do not recursively decode every string in an unknown document.
Test an object, an array and a broken value
Try the address object, an empty object, an array of two addresses and malformed text such as {"city":. The object guard should accept the first two as objects and reject the array and malformed value. Your required-field checks should then reject the empty object if city is required.
Inspect the final request in the JSON formatter before sending it. Confirm that address.city can be read as a nested path. If the only way to reach city is to parse address again, it is still stored as serialized text.
References
Primary references checked during preparation. Provider-specific contracts and native behavior still require review for your implementation.