Subscription row charts fail with "Series not found" after category mappings are processed twice
Describe the bug
A dashboard subscription fails to render a stacked horizontal bar chart on Metabase v1.58.31. The email displays "An error occurred while displaying this card", and the server logs TypeError: Series not found.
The question sums a numeric measure grouped by a text field and an integer category field. The category field has an internal mapping from integer IDs to text labels and is correctly configured as type/Category.
The question query completes successfully. Its results contain valid numeric measures, both category IDs, and their mapped labels. The dashboard card has no visualization overrides or additional series.
Source inspection points to the static row-chart renderer processing the category mappings twice. The first pass builds the mapping and removes the companion label column. The second pass replaces that mapping with an empty Map.
The isolated reproduction below confirms this mapping loss. It appears to explain the mismatch between the calculated series order and the series generated by the static row-chart renderer.
To Reproduce
To reproduce the mapping loss independently of the email configuration:
- Use the
v0.58.31source. - Run the following against
extractRemappedColumnsfromfrontend/src/metabase/visualizations/index.ts:
import { extractRemappedColumns } from "metabase/visualizations";
const data = {
cols: [
{
name: "category_id",
base_type: "type/Integer",
semantic_type: "type/Category",
remapped_to: "Category label",
},
{
name: "team",
base_type: "type/Text",
},
{
name: "sum",
base_type: "type/Float",
},
{
name: "Category label",
base_type: "type/Text",
remapped_from: "category_id",
},
],
rows: [
[1, "Team A", 10, "Type A"],
[1, "Team B", 20, "Type A"],
[2, "Team C", 30, "Type B"],
[2, "Team D", 40, "Type B"],
],
} as Parameters<typeof extractRemappedColumns>[0];
const first = extractRemappedColumns(data);
const second = extractRemappedColumns(first);
console.log([...first.cols[0].remapping!.entries()]);
console.log([...second.cols[0].remapping!.entries()]);
- Observe these results:
First call: [[1, "Type A"], [2, "Type B"]]
Second call: []
After the first call, the columns are category_id, team, and sum. The category column still has remapped_to: "Category label", but the companion label column has been removed.
On the second call, the existing mapping is replaced with an empty Map and cannot be rebuilt.
This is the sequence used by the subscription renderer: RenderChart processes remappings before calculating visualization settings, then StaticRowChart calls extractRemappedColumns again.
Expected behavior
Dashboard subscription emails render row charts with both groupings and the mapped category labels.
Processing an already-remapped dataset must preserve its existing mappings. The chart's series keys must remain consistent with the keys used to calculate its series order.
Logs
ERROR metabase.channel.render.card :: Pulse card render error
TypeError: TypeError: Series not found
at <js> :=>(file:/app/metabase.jar!/frontend_client/app/dist/lib-static-viz.bundle.js:73:5472647-5472675)
at <js> AD5(file:/app/metabase.jar!/frontend_client/app/dist/lib-static-viz.bundle.js:73:5472559-5472686)
at <js> ADZ(file:/app/metabase.jar!/frontend_client/app/dist/lib-static-viz.bundle.js:73:5469963-5470003)
at <js> AWA(file:/app/metabase.jar!/frontend_client/app/dist/lib-static-viz.bundle.js:73:6573542-6573551)
at <js> AW(file:/app/metabase.jar!/frontend_client/app/dist/lib-static-viz.bundle.js:1:667805-667810)
at <js> A(file:/app/metabase.jar!/frontend_client/app/dist/lib-static-viz.bundle.js:1:669310-669322)
at <js> Aj(file:/app/metabase.jar!/frontend_client/app/dist/lib-static-viz.bundle.js:1:669064-675576)
at <js> A(file:/app/metabase.jar!/frontend_client/app/dist/lib-static-viz.bundle.js:1:669538-669546)
at <js> Aj(file:/app/metabase.jar!/frontend_client/app/dist/lib-static-viz.bundle.js:1:669064-675576)
at org.graalvm.polyglot.Value.execute(Value.java:1049)
at metabase.channel.render.js.engine$execute_fn_name.invokeStatic(engine.clj:67)
at metabase.channel.render.js.engine$execute_fn_name.doInvoke(engine.clj:55)
at clojure.lang.RestFn.invoke(RestFn.java:493)
at metabase.channel.render.js.svg$_STAR_javascript_visualization_STAR_$fn__116614.invoke(svg.clj:210)
at metabase.channel.render.js.svg$do_with_static_viz_context.invokeStatic(svg.clj:92)
at metabase.channel.render.js.svg$do_with_static_viz_context.invoke(svg.clj:82)
at metabase.channel.render.js.svg$_STAR_javascript_visualization_STAR_.invokeStatic(svg.clj:209)
at metabase.channel.render.js.svg$_STAR_javascript_visualization_STAR_.invoke(svg.clj:206)
at metabase.channel.render.body$fn__116992$f__18629__auto____116993.invoke(body.clj:407)
Information about your Metabase installation
{
"browser-info": {
"language": "sv-SE",
"platform": "MacIntel",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36",
"vendor": "Google Inc."
},
"metabase-info": {
"databases": [
"postgres",
"sqlserver"
],
"run-mode": "prod",
"plan-alias": "enterprise-self-hosted",
"version": {
"date": "2026-08-19",
"tag": "v1.58.31",
"hash": "f90e03a"
},
"settings": {
"report-timezone": null
},
"hosting-env": "unknown",
"application-database": "postgres",
"application-database-details": {
"database": {
"name": "PostgreSQL",
"version": "17.9"
},
"jdbc-driver": {
"name": "PostgreSQL JDBC Driver",
"version": "42.7.12"
}
}
},
"system-info": {
"file.encoding": "UTF-8",
"java.runtime.name": "OpenJDK Runtime Environment",
"java.runtime.version": "21.0.11+10-LTS",
"java.vendor": "Eclipse Adoptium",
"java.vendor.url": "https://adoptium.net/",
"java.version": "21.0.11",
"java.vm.name": "OpenJDK 64-Bit Server VM",
"java.vm.version": "21.0.11+10-LTS",
"os.name": "Linux",
"os.version": "6.18.41-94.142.amzn2023.x86_64",
"user.language": "en",
"user.timezone": "GMT"
}
}
Severity
High. Negative customer impact for a common service. Blocks delivery of affected charts in recurring email reports.
Additional context
The relevant sequence in v0.58.31 is:
RenderChartcallsextractRemappings, which appliesextractRemappedColumnsto the datasets.StaticVisualizationtransforms the series and calculates visualization settings.StaticRowChartappliesextractRemappedColumnsagain.extractRemappedColumnsinitializes a new Map wheneverremapped_tois present. It does not preserve the existing mapping. The companionremapped_fromcolumn was removed by the first call.getOrderedSeriesthrowsTypeError("Series not found")when an enabled series-order key does not match a generated series.
This suggests that settings calculated with mapped labels become inconsistent with the series generated after the second extraction.
The affected question does not have an explicitly saved graph.series_order. Metabase calculates a default, so a saved custom order is not required for the observed failure.
The chart uses display: "row", two entries in graph.dimensions, one entry in graph.metrics, and stackable.stack_type: "stacked".
Source: metabase/metabase