"Metabase 1.4.2 breaks on GLPI 11: unhandled API renames break extraction, and a broken migration breaks the embedded dashboard entirely"
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 68/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- javascript, php
- Domain
- api, backend, data-visualization, frontend
Research direction
Start with the affected methods in apiclient.class.php, the embedded_token migration in config.class.php::install(), dashboard.class.php, and the AJAX URL construction in public/metabase.js. Reproduce extraction against the Metabase versions described, then exercise an upgrade with an existing token. Done means current and older API responses extract correctly, root collections and card metadata work, the button submits, and upgraded embedded dashboards no longer fail.
Written by the indexing model from the issue text.
Description
Code of Conduct
- I agree to follow this project's Code of Conduct
Is there an existing issue for this?
- I have searched the existing issues
GLPI Version
11.0.8
Plugin version
1.4.2
Bug description
Dashboard/question extraction is broken against current Metabase API versions. Several response fields the plugin reads under their old names were renamed by Metabase, and a newer native-question format ("MBQL 5") isn't handled at all. As a result:
PluginMetabaseAPIClient::getDashboardCards()returnsfalsefor every dashboard (readsordered_cards, which no longer exists — the API now returnsdashcards).PluginMetabaseAPIClient::getCards('root')never returns questions that are in the root collection (the API returnsid: "root"for that collection, but cards in it havecollection_id: null— the strict===comparison never matches).- Extracting a native question created with a current Metabase produces empty/
nullSQL and no template tags, becausedataset_query.native.query/dataset_query.native.template-tagsmoved todataset_query.stages[0].native/dataset_query.stages[0].template-tagsin current Metabase versions. - Card sizes come back empty in dashboard JSON extraction (
sizeX/sizeYrenamed tosize_x/size_y). - The "Extract" button in the collection list does nothing when GLPI's
root_docis empty (default install) —public/metabase.jsbuilds the AJAX URL asroot_doc + '/' + GLPI_PLUGINS_PATH.metabase + ..., which becomes//plugins/...and the browser resolves it as a request to a host namedpluginsinstead of a path.
I expected the "Extract questions" feature and dashboard card extraction to work against a current Metabase instance the same way they do with an older one. Instead they silently return nothing (no PHP error, no exception — the methods just return false/empty), which makes it look like there's simply nothing to extract.
I confirmed this is a real, reproducible bug (not a config/environment issue) by calling the affected methods directly against a live Metabase instance with real dashboards, both before and after patching — details and suggested fix below.
Second, more severe bug, also introduced in 1.4.2: upgrading a site that already had an embedded_token configured breaks the embedded dashboard on the Central page entirely with an uncaught exception (Lcobucci\JWT\Signer\InvalidKeyProvided: "Key cannot be empty"). 1.4.2 added embedded_token to secured_configs (setup.php) and expects it to be sodium-encrypted, but the migration meant to encrypt existing plain-text tokens on upgrade doesn't actually do that — see config.class.php::install():
// Encrypt embedded_token, previously stored in plain text
if (!array_key_exists('is_embedded_token_encrypted', $current_config) || !$current_config['is_embedded_token_encrypted']) {
if (!empty($current_config['embedded_token'])) {
Config::setConfigurationValues('plugin:metabase', [
'embedded_token' => $current_config['embedded_token'], // just rewrites the same plain-text value, never actually encrypts it
]);
}
Config::setConfigurationValues('plugin:metabase', ['is_embedded_token_encrypted' => 1]); // ...but marks it as encrypted anyway
}
dashboard.class.php then unconditionally does (new GLPIKey())->decrypt($config['embedded_token']) — decrypting a value that was never actually encrypted returns an empty string, which the JWT signer rejects. Any site that had embedded_token set before upgrading to 1.4.2 hits this immediately on the Central dashboard tab (fresh installs without a pre-existing token aren't affected).
Relevant log output
For the extraction bugs: none — no PHP error or exception, the affected methods simply return false/empty arrays.
For the embedded-dashboard bug:
[2026-08-05 20:44:23] glpi.CRITICAL: *** Uncaught PHP Exception Lcobucci\JWT\Signer\InvalidKeyProvided: "Key cannot be empty" at InvalidKeyProvided.php line 39
### Page URL
Setup > Metabase > (collection extraction dialog / dashboard "Extract questions" button) — not a public-facing page, it's the plugin's own admin UI.
### Steps To reproduce
**Extraction bugs:**
1. With Metabase plugin 1.4.2 configured against a current Metabase instance (reproduced on both v0.62 and v0.63.2)
2. Create a native SQL question and put it on a dashboard in Metabase (or use one in the root collection)
3. In GLPI, go to Setup > Metabase and try to extract that dashboard's questions / the root collection's questions
4. See empty result — no cards/questions come back, no error is shown anywhere
**Embedded dashboard bug:**
1. Have Metabase plugin working on an older version with `embedded_token` already configured (plain text, pre-`1.4.2`)
2. Update the plugin to `1.4.2`
3. Go to GLPI Central, open the "Painel Metabase" / embedded dashboard tab
4. See "Ocorreu um erro inesperado" / uncaught `InvalidKeyProvided` exception in `php-errors.log`
### Your GLPI setup information
GLPI version: 11.0.8
PHP version: 8.2.32 (cli, NTS)
Web server: Apache/2.4.68 (Debian)
Database: MariaDB 10.11.14
(Full System tab output from Setup > General > System can be attached if needed.)
Anything else?
Suggested fix — simple ?? fallbacks, kept backward-compatible with older Metabase versions:
// apiclient.class.php::getDashboardCards()
public function getDashboardCards($id)
{
$data = $this->httpQuery("dashboard/$id", [], 'GET');
return $data['dashcards'] ?? $data['ordered_cards'] ?? false;
}
// apiclient.class.php::getCards()
$normalized_id = $collection_id === 'root' ? null : $collection_id;
$cards = array_filter($cards, fn($card) => is_array($card)
&& array_key_exists('collection_id', $card)
&& $normalized_id === $card['collection_id']);
// config.class.php, wherever dataset_query.native.* / card sizes are read
$sql = $card['dataset_query']['native']['query']
?? $card['dataset_query']['stages'][0]['native'];
$size_x = $card['sizeX'] ?? $card['size_x'];
For the embedded-dashboard bug, the migration needs to actually encrypt the value instead of just flipping the flag, e.g.:
// config.class.php::install(), embedded_token migration block
if (!empty($current_config['embedded_token'])) {
$current_config['embedded_token'] = (new GLPIKey())->encrypt($current_config['embedded_token']);
Config::setConfigurationValues('plugin:metabase', [
'embedded_token' => $current_config['embedded_token'],
]);
}
(mirrors what the password migration a few lines above already does correctly.)
I have a working patch applying all of this cleanly on top of 1.4.2 (tested end-to-end against a live Metabase v0.63.2 instance with real dashboards — both the extraction features and the embedded dashboard) if it's useful as a starting point for a PR — happy to open one if that's welcome.
- Dominant language
- PHP
- Stars
- 17
- Forks
- 12
- Avg merge
- 1d 8m
- Merged PRs (30d)
- 2
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from pluginsGLPI/metabase
-
Difficulty 3/5 1-2 days Newbie friendliness 45/100
pluginsGLPI/metabase#156 ·
All issues in pluginsGLPI/metabase
Similar issues
-
priority: p3
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
googleapis/librarian#7636 ·
-
0. Needs triage bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
nextcloud/fulltextsearch#1011 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
phpstan/phpstan-doctrine#794 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
Automattic/static-site-importer#1767 ·