diff --git a/src/Entity/WorkflowState.php b/src/Entity/WorkflowState.php
index b3d4ae95a48c8aaee51ca2644938ed7b9dbffc41..9a13e5ad09023b789bf73d93f675e12845283774 100644
--- a/src/Entity/WorkflowState.php
+++ b/src/Entity/WorkflowState.php
@@ -498,6 +498,8 @@ class WorkflowState extends ConfigEntityBase implements WorkflowStateInterface {
       $options = $workflow->getStates(WorkflowInterface::ACTIVE_CREATION_STATES);
     }
     elseif ($current_sid) {
+      // This is called by FormatterBase->view();
+      // which calls WorkflowItem->getPossibleOptions();
       $transitions = $this->getTransitions($entity, $field_name, $account, $force);
     }
     elseif ($entity->{$field_name}->value ?? NULL) {
diff --git a/src/Entity/WorkflowTargetEntity.php b/src/Entity/WorkflowTargetEntity.php
index 48223d2a33972d5124b17ab02c8162e584dc754f..80461c25aa8001af8cdbecfc2a9bb51922cc1292 100644
--- a/src/Entity/WorkflowTargetEntity.php
+++ b/src/Entity/WorkflowTargetEntity.php
@@ -297,7 +297,7 @@ class WorkflowTargetEntity {
     $item = $entity->{$field_name}[0] ?? NULL;
     $transition ??= $item ? $item->getTransition() : NULL;
 
-    // For VBO, a dummy node has been created.
+    // For VBO, a dummy entity has been created.
     $transition ??= WorkflowTransition::create(['entity' => $entity, 'field_name' => $field_name]);
 
     return $transition;
diff --git a/src/Plugin/Field/FieldFormatter/WorkflowDefaultFormatter.php b/src/Plugin/Field/FieldFormatter/WorkflowDefaultFormatter.php
index f17d1f6431490a81170523c993bfe24d427ccce2..ce96f4976b709e5933105a0aae4559d00e496ee9 100644
--- a/src/Plugin/Field/FieldFormatter/WorkflowDefaultFormatter.php
+++ b/src/Plugin/Field/FieldFormatter/WorkflowDefaultFormatter.php
@@ -147,6 +147,11 @@ class WorkflowDefaultFormatter extends FormatterBase implements ContainerFactory
       return $elements;
     }
 
+    if (!$entity->{$field_name}->first()) {
+      // An entity can exist already before adding the workflow field.
+      return $elements;
+    }
+
     // Only build form if user has possible target state(s).
     $transition = $entity->{$field_name}->first()->getTransition();
     if (!WorkflowTransitionElement::showWidget($transition)) {
diff --git a/src/Plugin/Field/FieldType/WorkflowItem.php b/src/Plugin/Field/FieldType/WorkflowItem.php
index 1fc3d2ec0399b7c06ebf412f74330f58f688254e..799c611692cef1364fa43ba415ef358da5e6a245 100644
--- a/src/Plugin/Field/FieldType/WorkflowItem.php
+++ b/src/Plugin/Field/FieldType/WorkflowItem.php
@@ -248,9 +248,11 @@ class WorkflowItem extends ListItemBase {
    */
   public function getState() {
     $sid = $this->getStateId();
-    $wid = $this->getFieldDefinition()->getSetting('workflow_type');
-    $values = ['id' => $sid, 'wid' => $wid];
-    $state = WorkflowState::create($values);
+    $state = WorkflowState::load($sid)
+      ?? WorkflowState::create([
+        'id' => $sid,
+        'wid' => $this->getFieldDefinition()->getSetting('workflow_type'),
+      ]);
     return $state;
   }
 
@@ -283,22 +285,11 @@ class WorkflowItem extends ListItemBase {
       return $transition;
     }
 
-    // @todo Move to WorkflowTransition::getDefaultStateId().
     // Create a transition, to pass to the form.
-    $user = workflow_current_user();
+    // @todo $this->set('_workflow_transition'); (?)
     $entity = $this->getEntity();
     $field_name = $this->getParent()->getName();
-    $current_sid = $entity->isNew()
-      ? WorkflowTargetEntity::getCreationStateId($entity, $field_name)
-      : $this->value;
-
-    if (!$current_sid) {
-      return $transition;
-    }
-
-    $transition = WorkflowTransition::create([$current_sid, 'field_name' => $field_name])
-      ->setTargetEntity($entity);
-
+    $transition = WorkflowTransition::create(['entity' => $entity, 'field_name' => $field_name]);
     return $transition;
   }
 
@@ -406,9 +397,9 @@ class WorkflowItem extends ListItemBase {
       $field_name = $this->getParent()->getName();
       $user = workflow_current_user();
 
-      $sid = workflow_node_current_state($entity, $field_name);
-      $state = $workflow->getState($sid);
-      $allowed_options = $state->getOptions($entity, $field_name, $user, FALSE);
+      $field_config = $entity->get($field_name)->getFieldDefinition();
+      $field_storage = $field_config->getFieldStorageDefinition();
+      $allowed_options = workflow_state_allowed_values($field_storage, $entity);
     }
 
     return $allowed_options;
diff --git a/workflow.module b/workflow.module
index 4a50c92d60bc4e296b804d4e7ffa875625b48003..07a68556bdb3e9cee95124ff0b9e95db854aeeff 100644
--- a/workflow.module
+++ b/workflow.module
@@ -223,10 +223,10 @@ function workflow_state_allowed_values(FieldStorageDefinitionInterface $field_st
   // Note: $cacheable is a reference.
   $cacheable = FALSE;
 
+  $field_name = $field_storage_definition->getName();
   switch (TRUE) {
     case $entity instanceof WorkflowTransitionInterface:
       /** @var \Drupal\workflow\Entity\WorkflowTransitionInterface $entity */
-      $field_name = $field_storage_definition->getName();
       $state = match ($field_name) {
         'from_sid' => $entity->getFromState(),
         'to_sid' => $entity->getToState(),
@@ -266,9 +266,14 @@ function workflow_state_allowed_values(FieldStorageDefinitionInterface $field_st
       $allowed_options = WorkflowState::loadMultiple([], $wid);
       break;
 
+    case $entity instanceof EntityInterface:
     default:
-      // Should not happen.
       $allowed_options = [];
+      // An entity can exist already before adding the workflow field.
+      if ($item = $entity->{$field_name}->first()) {
+        $state = $item->getState();
+        $allowed_options = $state->getWorkflow()->getStates();
+      }
       break;
   }