Skip to content

List items that lose their type cannot be removed — the delete button is not rendered #7973

Description

@derekrussell

Describe the bug

When a list item using types ends up without its type key, ListControl renders it via renderErroneousTypedItem, which shows Error: item has no 'type' property. That row has no delete button and no drag handle, so there is no way to remove the broken item through the UI. The entry cannot be repaired from the CMS.

renderErroneousTypedItem passes onRemove but not allowRemove (or allowReorder):

<StyledListItemTopBar
  onCollapseToggle={null}
  onRemove={partial(this.handleRemove, index, key)}
  dragHandle={DragHandle}
  id={key}
/>

ListItemTopBar renders both controls only when the corresponding flag is also present:

{dragHandle && allowReorder ? <DragHandle Wrapper={dragHandle} id={id} /> : <span></span>}
{onRemove && allowRemove ? (
  <TopBarButton onClick={onRemove}>
    <Icon type="close" size="small" />
  </TopBarButton>
) : (
  <span></span>
)}

With both flags undefined, an empty <span> renders in place of each. The normal item path passes them (ListControl.js:696); the erroneous path is the only place that does not.

Introduced by #7573 (feat: add allow_remove and allow_reorder flags, 12 August 2025), which added the flags to the normal render path only.

To Reproduce

  1. Configure a list widget with types
  2. Get an item into the entry without its type key — editing the file directly is the simplest way, or via Editors' changes overwrite other sections when reordering typed list items #7956
  3. Open the entry in the CMS
  4. The item shows the error message, with no delete button and no drag handle

Expected behavior

An item that has lost its type can be deleted from the editor, so the entry can be repaired without editing the file by hand.

Screenshots

The first section has a drag handle and a delete button. The second, which has no type, has neither — just empty space where they belong.

Image

Suggested fix

Pass the flags in renderErroneousTypedItem as the normal path does:

allowRemove={field.get('allow_remove', true)}
allowReorder={field.get('allow_reorder', true)}

Applicable Versions:

  • Decap CMS version: 3.15.1, and current main (5cad3e13)
  • Git provider: GitHub
  • OS: macOS
  • Browser version: Chrome

Additional context

Found while investigating #7956. That issue produces exactly this state — an item written without its type — so the two compound: the CMS creates an item the editor then cannot delete. #7972 fixes the cause; this is about recovering when it has already happened.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions