No Code Attached Yet
avatar jjnxpct
jjnxpct
29 Jan 2026

Steps to reproduce the issue

  1. Install Joomla 5.4.2
  2. Install an extension that uses the legacy Bootstrap tab helpers (e.g., ConvertForms, DPCalendar, Edocman, or JCE Editor)
  3. Access a page that renders tabs using these helpers
  4. Check PHP error logs

Expected result

No PHP warnings should be generated when using the Bootstrap or UiTab helpers.

Actual result

PHP Warning is generated:
PHP Warning: Undefined array key "Joomla\CMS\HTML\Helpers\Bootstrap::startTabSet" in Bootstrap.php on line 884

Similar issue exists in /libraries/src/HTML/Helpers/UiTab.php on line 92.

System information (as much as possible)

  • Joomla Version: 5.4.2
  • PHP Version: 8.1+ (warning appears with PHP 8+ strict error checking)
  • Extensions triggering the issue: ConvertForms, DPCalendar, Edocman, JCE Editor

Additional comments

Root Cause:
Both Bootstrap.php (line 884) and UiTab.php (line 92) access array keys without checking if they exist:

$active = (static::$loaded[__CLASS__ . '::startTabSet'][$selector]['active'] == $id) ? ' active' : '';

Proposed Fix:
Add isset() check before accessing the array:

$active = (isset(static::$loaded[__CLASS__ . '::startTabSet'][$selector]['active']) && static::$loaded[__CLASS__ . '::startTabSet'][$selector]['active'] == $id) ? ' active' : '';

This defensive programming approach prevents warnings when extensions call addTab() but the initialization in startTabSet() didn't complete properly or the array key doesn't exist.

Files affected:

  • Bootstrap.ph line 884
  • UiTab.php line 92
avatar jjnxpct jjnxpct - open - 29 Jan 2026
avatar joomla-cms-bot joomla-cms-bot - change - 29 Jan 2026
Labels Added: No Code Attached Yet
avatar joomla-cms-bot joomla-cms-bot - labeled - 29 Jan 2026
avatar jjnxpct jjnxpct - change - 29 Jan 2026
The description was changed
avatar jjnxpct jjnxpct - edited - 29 Jan 2026
avatar jjnxpct jjnxpct - change - 29 Jan 2026
The description was changed
avatar jjnxpct jjnxpct - edited - 29 Jan 2026
avatar OctavianC
OctavianC - comment - 29 Jan 2026

Can't replicate this with the following code:

use Joomla\CMS\HTML\HTMLHelper;

echo HTMLHelper::_('uitab.startTabSet', 'test');
echo HTMLHelper::_('uitab.addTab', 'test', 'test-tab', 'Test Title');
echo 'test';
echo HTMLHelper::_('uitab.endTab');
echo HTMLHelper::_('uitab.addTab', 'test', 'test-tab2', 'Test Title 2');
echo 'test';
echo HTMLHelper::_('uitab.endTab');
echo HTMLHelper::_('uitab.endTabSet');

or

use Joomla\CMS\HTML\HTMLHelper;

echo HTMLHelper::_('bootstrap.startTabSet', 'test');
echo HTMLHelper::_('bootstrap.addTab', 'test', 'test-tab', 'Test Title');
echo 'test';
echo HTMLHelper::_('bootstrap.endTab');
echo HTMLHelper::_('bootstrap.addTab', 'test', 'test-tab2', 'Test Title 2');
echo 'test';
echo HTMLHelper::_('bootstrap.endTab');
echo HTMLHelper::_('bootstrap.endTabSet');
Image

I can only get a warning if I don't call startTabSet:

use Joomla\CMS\HTML\HTMLHelper;

//echo HTMLHelper::_('bootstrap.startTabSet', 'test');
echo HTMLHelper::_('bootstrap.addTab', 'test', 'test-tab', 'Test Title');
echo 'test';
echo HTMLHelper::_('bootstrap.endTab');
echo HTMLHelper::_('bootstrap.addTab', 'test', 'test-tab2', 'Test Title 2');
echo 'test';
echo HTMLHelper::_('bootstrap.endTab');
echo HTMLHelper::_('bootstrap.endTabSet');
Image

But that seems to me more of a misunderstanding on how the helper function works...

avatar jjnxpct
jjnxpct - comment - 29 Jan 2026

@OctavianC

After further investigation, I agree I cannot reproduce the specific circumstances that triggered the error or identify which extension/code path caused it.

The extensions using these helpers (ConvertForms, DPCalendar, JCE, Edocman) all properly call startTabSet in their code. You're right that the warning only appears when startTabSet isn't called correctly.

However, the isset() check would still be defensive programming - it would gracefully handle edge cases (incorrect extension usage, race conditions, etc.) without breaking functionality, simply defaulting to non-active state when the key doesn't exist.

That said, without concrete reproduction steps, I understand this might be insufficient for a core change.

avatar joomdonation joomdonation - change - 31 Jan 2026
Status New Closed
Closed_Date 0000-00-00 00:00:00 2026-01-31 04:29:34
Closed_By joomdonation
avatar joomdonation joomdonation - close - 31 Jan 2026
avatar joomdonation
joomdonation - comment - 31 Jan 2026

However, the isset() check would still be defensive programming - it would gracefully handle edge cases (incorrect extension usage, race conditions, etc.) without breaking functionality, simply defaulting to non-active state when the key doesn't exist.

Doing that would just hide the issue, so it is nothing better. Ideally, it should throw LogicException so that developer knows about the error (startTabSet needs to be called before calling addTab) but it would make current users unhappy.

So for the time being, I would leave it as how it is. If users see these notices, they can report to developers of the extensions and have the issue fixed properly. With that said, I will close this issue instead of having it stays open here forever. Feel free to re-open it if you do not agree. Thanks !

Add a Comment

Login with GitHub to post a comment