Variable scopedVars keys become undefined after upgrading to Grafana v12 – breaking custom datasource plugin

Hi Grafana Community,

We recently upgraded our Grafana instance from v10.4.19 to v12.4.3 and encountered a critical issue with variable passing in dashboards that use a custom datasource plugin (which is now deprecated and stopped updates since Jan 1st).

Problem Summary

  • In dashboards like “Service Report”, variables such as DeviceType, DeviceName, Active, Columns etc. are no longer passed correctly to the backend datasource service.

  • As a result, sub-device data (e.g., reachability and availability) cannot be retrieved.

Root Cause (observed)

By comparing the /query request payloads between v10 and v12, we found that the scopedVars structure has changed abnormally:

Grafana v10.4.19 (working as expected):

json

"scopedVars": {
  "DeviceType": {...},
  "DeviceName": {...},
  "Active": {...}
}

Grafana v12.4.3 (broken):

json

"scopedVars": {
  "undefined": {...}
}
  • All variable keys are replaced with the literal string "undefined".

  • Multiple variables are reduced to only the last one.

  • The targets[0].data field remains unchanged and still contains the correct variable values.

Additional Context

  • The custom datasource plugin acts as a bridge between Grafana and our backend service.

  • The plugin is no longer maintained (last update: Jan 1, 2023).

  • The issue only appears after upgrading to Grafana v12; v10 works fine.

  • We are aware that this might be a known Grafana v12 bug (still present in v13 according to some sources).

Our Question to the Community

  1. Is this a confirmed Grafana core bug related to scopedVars handling in v12+?

  2. Are there any known workarounds (e.g., plugin-side patches, configuration flags, or frontend hooks) that can restore correct variable passing without downgrading Grafana?

  3. If we were to develop a new custom datasource plugin to replace the deprecated one, what is the recommended way to retrieve dashboard variables reliably in v12+ (e.g., reading from targets[0].data instead of scopedVars)?

Environment

  • Grafana versions: v10.4.19 (working), v12.4.3 (broken), also tested v13 (still broken)

  • Datasource plugin: custom JSON/HTTP plugin (EOL since Jan 1, 2023)

  • Backend: custom service that receives transformed queries from the plugin

Hello @XMASyuan Welcome to grafana community
Yes this is caused by Grafana migration to the Scenes architecture in v11+ the new engine no longer correctly populates scopedVars with dashboard variable names instead all keys become the literal string undefined and still present in v13.


The targets[0].data field remains unchanged and still contains the correct variable values-> If your custom plugin already populates targets[0].data with variable values as you mentioned then your backend just needs to read from there instead of scopedVars → no plugin change needed.
However if targets[0].data is also empty, then the plugin itself needs to be patched to use getTemplateSrv().getVariables() to read variables and forward them to the backend.
For building a new plugin
Use getTemplateSrv().getVariables() from ‘@grafana/runtime’ inside the plugin’s query() method instead of relying on options.scopedVars
js
import { getTemplateSrv } from ‘@grafana/runtime’;
const variables = {};
getTemplateSrv().getVariables().forEach(v => {
variables[v.name] = {
text: v.current.text,
value: v.current.value
};
});
// use variables.DeviceType, variables.DeviceName etc.

@infofcc3 thank you very much for your response. I will share your test results and explanations with our development team.