No Code Attached Yet bug
avatar elh-ds
elh-ds
20 Mar 2026

What happened?

There are new custom field types (audio, video, document). When I create a new field, chose one of the new types and change it again before saving, the initial type is kept.

How to trigger it

  1. Create a new field and select type audio (don't save)
  2. Change it to video
  3. Fill in required options and save
  4. Go to an article, tab options

The field view still shows the type "audio" with follow-up errors, such as not being able to chose video formats

Version

6.1

Expected result

Select videos in the article's field.

Actual result

Image Only audio files can be selected.

System Information

No response

Additional Comments

The problem is the hidded types field
https://github.com/joomla/joomla-cms/blob/6.1-dev/plugins/fields/media/params/audio.xml#L33-L37

When the type is switched, the default value is kept.

avatar elh-ds elh-ds - open - 20 Mar 2026
avatar elh-ds elh-ds - change - 20 Mar 2026
Labels Added: bug
avatar elh-ds elh-ds - labeled - 20 Mar 2026
avatar joomla-cms-bot joomla-cms-bot - change - 20 Mar 2026
Labels Added: No Code Attached Yet
avatar joomla-cms-bot joomla-cms-bot - labeled - 20 Mar 2026
avatar chmst
chmst - comment - 20 Mar 2026

Confirmed

avatar tecpromotion
tecpromotion - comment - 20 Mar 2026

Thanks. Confirmed.

avatar crimle
crimle - comment - 20 Mar 2026

I can reproduce this.

avatar alikon
alikon - comment - 20 Mar 2026

@sergeytolkachyov can you have a look

avatar chmst
chmst - comment - 22 Mar 2026

It is not only these two fields. Same happens with for example images list and radio field, probably also in J5.4

avatar sergeytolkachyov
sergeytolkachyov - comment - 22 Mar 2026

@sergeytolkachyov can you have a look

Codex AI found this:

Summary
The problem in Joomla 6 is not in article rendering itself, but in the fact that when the type of a new custom field is changed, core never normalises jform[fieldparams] against the schema of the new type. Old keys remain in the data flow, and then com_fields only knows how to:

  1. load the XML for the new type into the form,
  2. serialise any fieldparams that happen to survive,
  3. later turn the stored fieldparams into real XML attributes of the field on the article form, without a whitelist.

That is why the UI already shows the second type, while some parameters of the first type continue to exist underneath.

Separately: in Joomla 6 core this is not AJAX. Changing the type performs a normal form submit with task=field.reload: admin-field-typehaschanged.js#L7.

Bug Data Flow

  1. The user selects the first type, for example imagelist.
    File: admin-field-typehaschanged.js#L7
    Here element.form.submit() is executed with task=field.reload.

  2. In reload(), the controller takes the entire jform payload as-is.
    File: FormController.php#L801
    Key points:

This is the primary defect in the flow: reload() does not clean fieldparams against the new type.

  1. After the redirect, the form takes its data from session state, not from the database.
    File: FieldModel.php#L924
    Critical line: FieldModel.php#L929

So if fieldparams from imagelist were present before the second type change, they come back as the live form data.

  1. For the new type, Joomla only loads that type's XML parameters.
    File: FieldsPlugin.php#L324
    This executes:
  • getFormPath(...)
  • load(file_get_contents($path), true, '/form/*')

Important: this loads the new type schema, but it does not purge the old fieldparams.

  1. If the old keys survive to save, FieldTable::bind() serialises them as-is.
    File: FieldTable.php#L82
    There is no logic here to "keep only keys allowed for the current type".
    There is only special handling for subform, and then:
  1. Later, on the article form, com_fields merges those parameters back into the field type again.
    File: FieldsPlugin.php#L245
    Critical points:

This is where the bug becomes visible in the article form.

How It Looks In The imagelist -> radio Case

  1. At the imagelist step, the form contains, for example:
  • fieldparams[directory]
  • fieldparams[multiple]
  • fieldparams[image_class]

Schema: imagelist.xml

  1. The user does not save, but changes the type to radio.
    At the moment of submit, the current form is still the imagelist form, so the old fieldparams[*] are submitted to field.reload.

  2. reload() stores them in session state together with the already changed type=radio.

  3. For radio, the UI is rebuilt using the radio schema:
    radio.xml

But this does not mean the old keys have been removed at the data level.

  1. If those old keys make it into the saved record's fieldparams, then when the field is built on the article form:
  • the radio plugin receives its own type,
  • FieldsPlugin::onCustomFieldsPrepareDom() performs the merge,
  • and <field ...> may again receive directory, multiple, image_class, and other foreign attributes.

For radio, this is particularly visible because some foreign attributes affect the resulting DOM even though they do not exist in radio.xml.

Why The Bug Appears "Random"

  • It depends on the specific pair of types.
  • It is only noticeable when an old key conflicts with the behaviour of the new field type.
  • Arrays and empty values are partially dropped, while scalar values pass through.
  • Because of that, sometimes "everything" survives, and sometimes only "part" of the attributes survive.

Root Cause
The root cause is not a single method, but a broken invariant in the flow:

type changed
-> old fieldparams are not purged
-> the new XML schema is only loaded on top
-> at save time there is no mandatory server-side sanitisation of fieldparams against the current type schema
-> at render time all stored scalar fieldparams are turned back into XML attributes

In short: after a type change, Joomla changes the form, but it does not rebuild the field data to match the new type.

What I Would Consider The Correct Fix
There are two realistic places to fix this properly:

  1. In reload(), rebuild fieldparams against the new type form before writing to setUserState().
  2. Or, in FieldModel/FieldTable, enforce a strict server-side filter of fieldparams against the XML definition of the current field type before bind() / save.

The second option is more reliable, because it fixes not only the UI transition case, but the data model itself.

avatar HLeithner HLeithner - change - 25 Mar 2026
Status New Closed
Closed_Date 0000-00-00 00:00:00 2026-03-25 10:03:19
Closed_By HLeithner
avatar HLeithner HLeithner - close - 25 Mar 2026
avatar HLeithner
HLeithner - comment - 25 Mar 2026

We have a pull request which fixes this issue, please text. #47468

Add a Comment

Login with GitHub to post a comment