Summary
client.GetAllAsync<DataSource>(filter, ...) throws a JsonSerializationException for any DataSource whose DataPoints have a populated statusDisplayNames field:
Unexpected character encountered while parsing value: {. Path 'items[N].dataPoints[M].statusDisplayNames', line NNNN, position 13.
Root cause
GET /setting/datasources/{id}?fields=id,name,dataPoints returns dataPoints[].statusDisplayNames as an array of objects, e.g.:
"statusDisplayNames": [
{ "id": 133, "datapointId": 561, "statusDisplayName": "Unknown", "operator": "EQ", "metricValue": "-1" },
{ "id": 134, "datapointId": 561, "statusDisplayName": "Not Connected", "operator": "EQ", "metricValue": "0" },
{ "id": 135, "datapointId": 561, "statusDisplayName": "Connected", "operator": "EQ", "metricValue": "1" }
]
but the DataPoint.StatusDisplayNames model property is apparently typed to expect something else (a string/simple list), so the object entries fail to deserialize.
Repro
GET /setting/datasources/101 (a Palo Alto Prisma SD-WAN edge-health DataSource) via raw REST — succeeds, and shows the array-of-objects shape above for one of its datapoints.
client.GetAllAsync<DataSource>(filter, default) including this DataSource in the result set — throws the parse error shown above.
- Confirmed via the
logicmonitor skill in panoramicdata/PanoramicData.Skills: dotnet LogicMonitor.cs --profile <p> datasources --filter "<term>" throws this for any tenant that has DataSources with populated statusDisplayNames, while filters matching only "plain" DataSources succeed.
Impact
Any typed GetAllAsync<DataSource> (or similar) call fails outright as soon as a single matching DataSource has a populated statusDisplayNames array — there's no way to inspect DataSources by name/filter through the typed API once one bad apple is in the result set.
Suggested fix
Model DataPoint.StatusDisplayNames as List<DataPointStatusDisplayName> (or equivalent) matching the wire shape (id, datapointId, statusDisplayName, operator, metricValue), rather than whatever simpler type it's currently declared as.
Workaround in the meantime
raw-rest (unauthenticated-model, direct JSON) is unaffected — e.g. raw-rest GET "/setting/datasources?filter=name~%22<term>%22&fields=id,name,group,appliesTo" returns correctly even for DataSources that crash the typed datasources list command. Use that when a datasources --filter call throws this error.
Context
Discovered while planning a LogicMonitor executive dashboard — a datasources --filter crash briefly hid the fact that a relevant SD-WAN DataSource existed in the portal, leading to an incorrect assumption about available SD-WAN platforms until traced back to this bug. Non-blocking — the raw-rest workaround above is sufficient for now.
Summary
client.GetAllAsync<DataSource>(filter, ...)throws aJsonSerializationExceptionfor any DataSource whose DataPoints have a populatedstatusDisplayNamesfield:Root cause
GET /setting/datasources/{id}?fields=id,name,dataPointsreturnsdataPoints[].statusDisplayNamesas an array of objects, e.g.:but the
DataPoint.StatusDisplayNamesmodel property is apparently typed to expect something else (a string/simple list), so the object entries fail to deserialize.Repro
GET /setting/datasources/101(a Palo Alto Prisma SD-WAN edge-health DataSource) via raw REST — succeeds, and shows the array-of-objects shape above for one of its datapoints.client.GetAllAsync<DataSource>(filter, default)including this DataSource in the result set — throws the parse error shown above.logicmonitorskill inpanoramicdata/PanoramicData.Skills:dotnet LogicMonitor.cs --profile <p> datasources --filter "<term>"throws this for any tenant that has DataSources with populatedstatusDisplayNames, while filters matching only "plain" DataSources succeed.Impact
Any typed
GetAllAsync<DataSource>(or similar) call fails outright as soon as a single matching DataSource has a populatedstatusDisplayNamesarray — there's no way to inspect DataSources by name/filter through the typed API once one bad apple is in the result set.Suggested fix
Model
DataPoint.StatusDisplayNamesasList<DataPointStatusDisplayName>(or equivalent) matching the wire shape (id,datapointId,statusDisplayName,operator,metricValue), rather than whatever simpler type it's currently declared as.Workaround in the meantime
raw-rest(unauthenticated-model, direct JSON) is unaffected — e.g.raw-rest GET "/setting/datasources?filter=name~%22<term>%22&fields=id,name,group,appliesTo"returns correctly even for DataSources that crash the typeddatasourceslist command. Use that when adatasources --filtercall throws this error.Context
Discovered while planning a LogicMonitor executive dashboard — a
datasources --filtercrash briefly hid the fact that a relevant SD-WAN DataSource existed in the portal, leading to an incorrect assumption about available SD-WAN platforms until traced back to this bug. Non-blocking — the raw-rest workaround above is sufficient for now.