How can I make a custom content entity ID editable on the content entity form? I've created a custom content entity with a string ID field named 'lot_number':

*   entity_keys = {
*     "id" = "lot_number",


This is its field definition:

$fields['lot_number'] = BaseFieldDefinition::create('string')
  -&gt;setLabel(t('Lot Number'))
  -&gt;setDescription(t('Unique alphanumeric lot number for a batch of inventory.'))
  -&gt;setRequired(TRUE)
  -&gt;setSetting('max_length', 20)
  -&gt;setDisplayOptions('view', array(
    'label' =&gt; 'inline',
    'type' =&gt; 'string',
    'weight' =&gt; 10,
  ))
  -&gt;setDisplayOptions('form', array(
    'type' =&gt; 'string_textfield',      
    'weight' =&gt; 10,
    'settings' =&gt; array(
      'size' =&gt; '10',
      ),
  ))
  -&gt;setDisplayConfigurable('form', TRUE)
  -&gt;setDisplayConfigurable('view', TRUE)
  -&gt;addConstraint('UniqueField', []);


My problem is that this lot_number field does not show up on the content entity form. I tried adding it to the form programmatically in the buildForm() method of my form controller (that extends ContentEntityForm.) The following code gets it to show up on the form:

$form['lot_number'] = [
  '#type' =&gt; 'machine_name',
  '#title' =&gt; $this-&gt;t('Lot Number'),
  '#weight' =&gt; 10,
  '#size' =&gt; 20,
  '#maxlength' =&gt; 20,
  '#required' =&gt; TRUE,
  '#default_value' =&gt; $lot_master-&gt;getLotNumber(),
  '#machine_name' =&gt; [
    'exists' =&gt; '\Drupal\galt_inv\Entity\LotMaster::load',
  ],
  '#disabled' =&gt; !$lot_master-&gt;isNew(),
];


However, when I attempt to submit the form, I get an error message:

Error: Cannot unset string offsets in Drupal\Core\Field\WidgetBase-&gt;extractFormValues() (line 354 of core/lib/Drupal/Core/Field/WidgetBase.php).


I tried changing $form['lot_number'] to $form['lot_number']['widget'][0] in an attempt to make it match the rest of the form elements, but that didn't work at all.

Is there some simple way to get a content entity ID onto the content entity edit form? Any advice would be greatly appreciated.
You have both a widget configured and a custom form element, that results in Drupal being confused about the structure.

If you have a form element defined by yourself, don't define form display options and you should be OK.

The reason the widget show up like with other fields is likely actually a regression with the security fix in 8.3.1 that denies edit access to the entity. When we did that, we didn't anticipate a use case like this. You could override the default fieldAccess() method on the EntityAccessControlHandler to grant edit access to the id field, at least when it is new.

Or you do not make the lot number the actual entity ID but have a technical auto-increment ID, then you don't have to worry about this stuff.