Summary
The InsightParser cannot parse line graph insights from the current PostHog API. The parser expects time-series data as [[date, value], ...] pairs, but the API returns a single series object containing separate data and days arrays. This causes all line graph insights to silently fail detection and display as zero/error.
Root Cause
In InsightParser::private_hasLineGraphStructure() (InsightParser.cpp L187-219), the very first check fails:
JsonArrayConst timeseriesData = firstResult[JSON_KEY_RESULT];
if (timeseriesData.isNull() || timeseriesData.size() <= 1) return false;
// "Needs at least 2 points for a line graph"
results[0].result has 1 element (the series object), so size() <= 1 is true and detection bails immediately.
What the parser expects
{
"results": [{
"result": [
["2026-01-13", 8],
["2026-01-14", 2],
["2026-01-15", 13]
]
}]
}
The data extraction methods (getSeriesYValues, getSeriesXLabel, getSeriesRange) all read result[i][0] as a date string and result[i][1] as a numeric value.
What the PostHog API actually returns
{
"results": [{
"result": [{
"data": [8, 2, 13, 19, 5, 5, 7, ...],
"days": ["2026-01-13", "2026-01-14", "2026-01-15", ...],
"labels": ["13-Jan-2026", "14-Jan-2026", "15-Jan-2026", ...],
"count": 155,
"label": "$pageview"
}]
}]
}
This format is returned regardless of whether the insight is created with the legacy filters parameter or the new query parameter.
Additionally: query.display is not populated for new-format insights
For insights created with the new InsightVizNode / TrendsQuery format:
filters is {} (empty)
query.display does not exist (display is at query.source.trendsFilter.display)
This breaks the fallback display-type check on L204-207. Insights created with the legacy filters param have query: null, so this check also fails.
Suggested Fix
Update private_hasLineGraphStructure() and the data extraction methods to handle the current format:
bool InsightParser::private_hasLineGraphStructure() const {
if (!valid) return false;
JsonArrayConst results = m_insightDataRoot[JSON_KEY_RESULTS];
if (results.isNull() || results.size() == 0) return false;
JsonObjectConst firstResult = results[0];
if (firstResult.isNull()) return false;
JsonArrayConst resultArray = firstResult[JSON_KEY_RESULT];
if (resultArray.isNull() || resultArray.size() == 0) return false;
JsonVariantConst firstElement = resultArray[0];
// New format: result[0] is an object with "data" and "days" arrays
if (firstElement.is<JsonObjectConst>()) {
JsonObjectConst series = firstElement.as<JsonObjectConst>();
JsonArrayConst data = series["data"];
JsonArrayConst days = series["days"];
return !data.isNull() && !days.isNull() && data.size() >= 2;
}
// Legacy format: result is [[date, value], [date, value], ...]
if (resultArray.size() <= 1) return false;
JsonArrayConst firstPoint = resultArray[0];
if (firstPoint.isNull() || firstPoint.size() != 2) return false;
const char* dateStr = firstPoint[0];
if (!dateStr || strlen(dateStr) < 10) return false;
return firstPoint[1].is<double>();
}
Similarly, getSeriesPointCount, getSeriesYValues, getSeriesXLabel, and getSeriesRange would need to read from result[0].data and result[0].days instead of result[i][0] / result[i][1].
Impact
- BoldNumber insights work (the
aggregated_value field is present in the current API format)
- Line graphs are completely broken for all users
- Funnel insights may also be affected depending on their API format
Environment
- Firmware: 0.1.5
- PostHog region: US
- Parser source: current
main branch has the same issue
Summary
The
InsightParsercannot parse line graph insights from the current PostHog API. The parser expects time-series data as[[date, value], ...]pairs, but the API returns a single series object containing separatedataanddaysarrays. This causes all line graph insights to silently fail detection and display as zero/error.Root Cause
In
InsightParser::private_hasLineGraphStructure()(InsightParser.cpp L187-219), the very first check fails:results[0].resulthas 1 element (the series object), sosize() <= 1is true and detection bails immediately.What the parser expects
{ "results": [{ "result": [ ["2026-01-13", 8], ["2026-01-14", 2], ["2026-01-15", 13] ] }] }The data extraction methods (
getSeriesYValues,getSeriesXLabel,getSeriesRange) all readresult[i][0]as a date string andresult[i][1]as a numeric value.What the PostHog API actually returns
{ "results": [{ "result": [{ "data": [8, 2, 13, 19, 5, 5, 7, ...], "days": ["2026-01-13", "2026-01-14", "2026-01-15", ...], "labels": ["13-Jan-2026", "14-Jan-2026", "15-Jan-2026", ...], "count": 155, "label": "$pageview" }] }] }This format is returned regardless of whether the insight is created with the legacy
filtersparameter or the newqueryparameter.Additionally:
query.displayis not populated for new-format insightsFor insights created with the new
InsightVizNode/TrendsQueryformat:filtersis{}(empty)query.displaydoes not exist (display is atquery.source.trendsFilter.display)This breaks the fallback display-type check on L204-207. Insights created with the legacy
filtersparam havequery: null, so this check also fails.Suggested Fix
Update
private_hasLineGraphStructure()and the data extraction methods to handle the current format:Similarly,
getSeriesPointCount,getSeriesYValues,getSeriesXLabel, andgetSeriesRangewould need to read fromresult[0].dataandresult[0].daysinstead ofresult[i][0]/result[i][1].Impact
aggregated_valuefield is present in the current API format)Environment
mainbranch has the same issue