diff --git a/pydra/engine/core.py b/pydra/engine/core.py
index f5c8c931..c2f05697 100644
--- a/pydra/engine/core.py
+++ b/pydra/engine/core.py
@@ -462,7 +462,6 @@ class Workflow(TaskBase):
 
         # store output connections
         self._connections = None
-        self.node_names = []
 
     def __getattr__(self, name):
         if name == "lzin":
@@ -493,22 +492,37 @@ class Workflow(TaskBase):
         return self.graph.sorted_nodes
 
     def add(self, task):
+        """adding a task to the workflow"""
         if not is_task(task):
             raise ValueError("Unknown workflow element: {!r}".format(task))
         self.graph.add_nodes(task)
         self.name2obj[task.name] = task
         self._last_added = task
+        self.create_connections(task)
+        logger.debug(f"Added {task}")
+        self.inputs._graph = self.graph_sorted
+        return self
+
+    def create_connections(self, task):
+        """creating connections between tasks"""
         other_states = {}
         for field in dc.fields(task.inputs):
             val = getattr(task.inputs, field.name)
             if isinstance(val, LazyField):
                 # adding an edge to the graph if task id expecting output from a different task
                 if val.name != self.name:
+                    # checking if the connection is already in the graph
+                    if (getattr(self, val.name), task) in self.graph.edges:
+                        continue
                     self.graph.add_edges((getattr(self, val.name), task))
                     logger.debug("Connecting %s to %s", val.name, task.name)
-                if val.name in self.node_names and getattr(self, val.name).state:
-                    # adding a state from the previous task to other_states
-                    other_states[val.name] = (getattr(self, val.name).state, field.name)
+
+                    if getattr(self, val.name).state:
+                        # adding a state from the previous task to other_states
+                        other_states[val.name] = (
+                            getattr(self, val.name).state,
+                            field.name,
+                        )
         # if task has connections state has to be recalculated
         if other_states:
             if hasattr(task, "fut_combiner"):
@@ -517,10 +531,6 @@ class Workflow(TaskBase):
                 )
             else:
                 task.state = state.State(task.name, other_states=other_states)
-        self.node_names.append(task.name)
-        logger.debug(f"Added {task}")
-        self.inputs._graph = self.graph_sorted
-        return self
 
     async def _run(self, submitter=None, **kwargs):
         self.inputs = dc.replace(self.inputs, **kwargs)
@@ -530,7 +540,9 @@ class Workflow(TaskBase):
         result = self.result()
         if result is not None:
             return result
-
+        # creating connections that were defined after adding tasks to the wf
+        for task in self.graph.nodes:
+            self.create_connections(task)
         """
         Concurrent execution scenarios
 

edges not created if input set after `wf.add`
see the xfailing `test_wf_2b`: https://github.com/nipype/pydra/blob/master/pydra/engine/tests/test_workflow.py#L95

compare with `test_wf_2` and `test_wf_2a`
diff --git a/pydra/engine/tests/test_workflow.py b/pydra/engine/tests/test_workflow.py
index 97823fdc..76eb4579 100644
--- a/pydra/engine/tests/test_workflow.py
+++ b/pydra/engine/tests/test_workflow.py
@@ -151,10 +151,6 @@ def test_wf_2a(plugin):
     assert wf.output_dir == odir
 
 
-@pytest.mark.xfail(
-    reason="x=lzout added after calling wf.add(add2_task):"
-    "edge is not created (fix: creating edges in run?)"
-)
 @pytest.mark.parametrize("plugin", Plugins)
 def test_wf_2b(plugin):
     """ workflow with 2 tasks, no splitter

pip install -e .[all]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist pytest-mock pytest-asyncio
apt-get update apt-get install -y gcc
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
cachetools==5.5.2
certifi==2025.1.31
charset-normalizer==3.4.1
click==8.1.8
cloudpickle==3.1.1
codecov==2.1.13
coverage==7.8.0
dask==2024.8.0
distributed==2024.8.0
exceptiongroup==1.2.2
execnet==2.1.1
filelock==3.18.0
frozendict==2.4.6
fsspec==2025.3.1
idna==3.10
importlib_metadata==8.6.1
iniconfig==2.1.0
Jinja2==3.1.6
locket==1.0.0
lxml==5.3.1
MarkupSafe==3.0.2
msgpack==1.1.0
packaging==24.2
partd==1.4.2
platformdirs==4.3.7
pluggy==1.5.0
psutil==7.0.0
-e git+https://github.com/nipype/pydra.git@71cfc9f2c6cfeffa2714804e6bbf4a67b0167b7e#egg=pydra
PyLD==2.0.4
pytest==8.3.5
pytest-asyncio==0.26.0
pytest-cov==6.0.0
pytest-env==1.1.5
pytest-mock==3.14.0
pytest-xdist==3.6.1
PyYAML==6.0.2
requests==2.32.3
sortedcontainers==2.4.0
tblib==3.0.0
tomli==2.2.1
toolz==1.0.0
tornado==6.4.2
typing_extensions==4.13.0
urllib3==2.3.0
yapf==0.43.0
zict==3.0.0
zipp==3.21.0

name: pydra
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - cachetools==5.5.2
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - click==8.1.8
      - cloudpickle==3.1.1
      - codecov==2.1.13
      - coverage==7.8.0
      - dask==2024.8.0
      - distributed==2024.8.0
      - exceptiongroup==1.2.2
      - execnet==2.1.1
      - filelock==3.18.0
      - frozendict==2.4.6
      - fsspec==2025.3.1
      - idna==3.10
      - importlib-metadata==8.6.1
      - iniconfig==2.1.0
      - jinja2==3.1.6
      - locket==1.0.0
      - lxml==5.3.1
      - markupsafe==3.0.2
      - msgpack==1.1.0
      - packaging==24.2
      - partd==1.4.2
      - platformdirs==4.3.7
      - pluggy==1.5.0
      - psutil==7.0.0
      - pyld==2.0.4
      - pytest==8.3.5
      - pytest-asyncio==0.26.0
      - pytest-cov==6.0.0
      - pytest-env==1.1.5
      - pytest-mock==3.14.0
      - pytest-xdist==3.6.1
      - pyyaml==6.0.2
      - requests==2.32.3
      - sortedcontainers==2.4.0
      - tblib==3.0.0
      - tomli==2.2.1
      - toolz==1.0.0
      - tornado==6.4.2
      - typing-extensions==4.13.0
      - urllib3==2.3.0
      - yapf==0.43.0
      - zict==3.0.0
      - zipp==3.21.0
prefix: /opt/conda/envs/pydra

pydra/engine/tests/test_workflow.py::test_wf_2b[cf]
pydra/engine/tests/test_workflow.py::test_wf_st_1[cf] pydra/engine/tests/test_workflow.py::test_wf_st_1_call_subm[cf] pydra/engine/tests/test_workflow.py::test_wf_st_1_call_plug[cf] pydra/engine/tests/test_workflow.py::test_wf_ndst_1[cf] pydra/engine/tests/test_workflow.py::test_wf_st_2[cf] pydra/engine/tests/test_workflow.py::test_wf_ndst_2[cf] pydra/engine/tests/test_workflow.py::test_wf_st_3[cf] pydra/engine/tests/test_workflow.py::test_wf_ndst_3[cf] pydra/engine/tests/test_workflow.py::test_wf_st_4[cf] pydra/engine/tests/test_workflow.py::test_wf_ndst_4[cf] pydra/engine/tests/test_workflow.py::test_wf_st_5[cf] pydra/engine/tests/test_workflow.py::test_wf_ndst_5[cf] pydra/engine/tests/test_workflow.py::test_wf_st_6[cf] pydra/engine/tests/test_workflow.py::test_wf_ndst_6[cf] pydra/engine/tests/test_workflow.py::test_wf_st_7[cf] pydra/engine/tests/test_workflow.py::test_wf_ndst_7[cf] pydra/engine/tests/test_workflow.py::test_wf_st_8[cf] pydra/engine/tests/test_workflow.py::test_wf_ndst_8[cf] pydra/engine/tests/test_workflow.py::test_wf_st_9[cf] pydra/engine/tests/test_workflow.py::test_wf_ndst_9[cf] pydra/engine/tests/test_workflow.py::test_wf_st_singl_1[cf] pydra/engine/tests/test_workflow.py::test_wf_ndst_singl_1[cf] pydra/engine/tests/test_workflow.py::test_wf_st_singl_2[cf] pydra/engine/tests/test_workflow.py::test_wf_ndst_singl_2[cf] pydra/engine/tests/test_workflow.py::test_wfasnd_st_1[cf] pydra/engine/tests/test_workflow.py::test_wfasnd_ndst_1[cf] pydra/engine/tests/test_workflow.py::test_wfasnd_wfst_1[cf] pydra/engine/tests/test_workflow.py::test_wfasnd_st_2[cf] pydra/engine/tests/test_workflow.py::test_wfasnd_wfst_2[cf] pydra/engine/tests/test_workflow.py::test_wfasnd_ndst_3[cf] pydra/engine/tests/test_workflow.py::test_wfasnd_wfst_3[cf] pydra/engine/tests/test_workflow.py::test_wf_state_cachelocations[cf] pydra/engine/tests/test_workflow.py::test_wf_state_n_nostate_cachelocations[cf]
pydra/engine/tests/test_workflow.py::test_wf_1[cf] pydra/engine/tests/test_workflow.py::test_wf_1_call_subm[cf] pydra/engine/tests/test_workflow.py::test_wf_1_call_plug[cf] pydra/engine/tests/test_workflow.py::test_wf_1_call_exception[cf] pydra/engine/tests/test_workflow.py::test_wf_2[cf] pydra/engine/tests/test_workflow.py::test_wf_2a[cf] pydra/engine/tests/test_workflow.py::test_wfasnd_1[cf] pydra/engine/tests/test_workflow.py::test_wfasnd_wfinp_1[cf] pydra/engine/tests/test_workflow.py::test_wf_nostate_cachedir[cf] pydra/engine/tests/test_workflow.py::test_wf_nostate_cachedir_relativepath[cf] pydra/engine/tests/test_workflow.py::test_wf_nostate_cachelocations[cf] pydra/engine/tests/test_workflow.py::test_wf_nostate_cachelocations_updated[cf] pydra/engine/tests/test_workflow.py::test_wf_nostate_cachelocations_recompute[cf]
pydra/engine/core.py
pydra/engine/core.py