Skip to content

Virtual fields are editable in admin UI despite values being discarded #16013

@jhb-dev

Description

@jhb-dev

Describe the Bug

Virtual fields (virtual: true or virtual: "path") render as normal editable inputs in the admin panel. Users can type into them, but the input is never persisted — it's silently discarded on save and overwritten on the next read (by hooks, built-in virtual population, or plugin logic).

This is confusing because nothing in the UI indicates the field is virtual or that edits won't be saved.

Reproduction Steps

  1. Add a virtual field to a collection:
{
  name: 'computedTitle',
  type: 'text',
  virtual: true,
  hooks: {
    afterRead: [({ siblingData }) => `Generated: ${siblingData.title}`],
  },
}
  1. Open the admin panel, edit a document in that collection
  2. The computedTitle field is a normal editable text input
  3. Type something into it and save
  4. On reload, the user's input is gone — replaced by the hook value

Expected behavior

Virtual fields should default to admin.readOnly: true since they are not user-editable. Users who explicitly set admin.readOnly: false could override this if they have a reason to (e.g. custom component that handles the input differently).

Root cause

In packages/payload/src/fields/config/sanitize.ts and packages/ui/src/forms/RenderFields/index.tsx, there is no logic that checks virtual when determining readOnly. Virtual fields are treated identically to regular persisted fields.

Workaround

{
  name: 'computedTitle',
  type: 'text',
  virtual: true,
  admin: { readOnly: true },
  // ...
}

Affected areas

  • area: core
  • area: ui

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