diff --git a/dotscience/__init__.py b/dotscience/__init__.py
index e12da54..c2c3ac3 100644
--- a/dotscience/__init__.py
+++ b/dotscience/__init__.py
@@ -253,6 +253,9 @@ class Dotscience:
     currentRun = None
 
     def __init__(self):
+        self._reset()
+
+    def _reset(self):
         self._mode = None
         self._workload_file = None
         self._root = os.getenv('DOTSCIENCE_PROJECT_DOT_ROOT', default=os.getcwd())
@@ -269,6 +272,7 @@ class Dotscience:
         # TODO: make publish etc fail if we're not connected in remote mode.
         if not project:
             raise Exception("Please specify a project name as the third argument to ds.connect()")
+        self._reset()
         self._dotmesh_client = DotmeshClient(
             cluster_url=hostname + "/v2/dotmesh/rpc",
             username=username,

diff --git a/dotscience/test_dotscience.py b/dotscience/test_dotscience.py
index 92790c7..89ab7e9 100644
--- a/dotscience/test_dotscience.py
+++ b/dotscience/test_dotscience.py
@@ -857,3 +857,39 @@ def test_multi_publish_2():
     assert m1["__ID"] != m2["__ID"]
     assert m1["start"] != m2["start"]
     assert m1["end"] != m2["end"]
+
+
+def test_reconnect_resets_internal_state(monkeypatch):
+    class FakeDotmeshClient:
+        def __init__(self, cluster_url, username, api_key):
+            self.cluster_url = cluster_url
+            self.username = username
+            self.api_key = api_key
+
+        def ping(self):
+            pass
+
+    monkeypatch.setattr(dotscience, "DotmeshClient", FakeDotmeshClient)
+
+    ds = dotscience.Dotscience()
+    ds.connect("me", "pass", "myproj", "https://example.com")
+    assert ds._dotmesh_client.__dict__ == {
+        "cluster_url": "https://example.com/v2/dotmesh/rpc",
+        "username": "me",
+        "api_key": "pass",
+    }
+    assert ds._project_name == "myproj"
+
+    # Pretend we have a cached project:
+    ds._cached_project = "not empty"
+    assert ds._get_project_or_create("myproj") == "not empty"
+
+    # Now, reconnect:
+    ds.connect("me2", "pass2", "myproj2", "https://2.example.com")
+    assert ds._dotmesh_client.__dict__ == {
+        "cluster_url": "https://2.example.com/v2/dotmesh/rpc",
+        "username": "me2",
+        "api_key": "pass2",
+    }
+    assert ds._project_name == "myproj2"
+    assert ds._cached_project == None

ds.connect() only connects to single project and runs overwritten [fusemachines]
Fuse machines run ds.connect() from a local machine but it only connects to a single project.

Also runs are getting overwritten when running on the same machine.

This text is just a placeholder: it was decided on the Fuse machines call Oct 21st 4-5pm BST that they may need to do a call with the support engineer to fully explain. And/or send a video/screenshots.

Link to description from Fuse Machines: https://docs.google.com/document/d/1ZLhKlW6AG3khlPVyrINXD3LaS1fSTilyEorrj66w9ow
dotscience/test_dotscience.py::test_reconnect_resets_internal_state
dotscience/test_dotscience.py::test_input_1b dotscience/test_dotscience.py::test_run_parameter_1 dotscience/test_dotscience.py::test_run_output_2 dotscience/test_dotscience.py::test_multi_publish_2 dotscience/test_dotscience.py::test_notice_jupyter_mode dotscience/test_dotscience.py::test_explicit_script_name dotscience/test_dotscience.py::test_notice_command_mode dotscience/test_dotscience.py::test_label_1a dotscience/test_dotscience.py::test_summary_1a dotscience/test_dotscience.py::test_parameter_n dotscience/test_dotscience.py::test_run_input_n dotscience/test_dotscience.py::test_parameter_1a dotscience/test_dotscience.py::test_run_summary_1 dotscience/test_dotscience.py::test_conflicting_mode_2 dotscience/test_dotscience.py::test_run_input_relative dotscience/test_dotscience.py::test_run_input_2 dotscience/test_dotscience.py::test_run_summary_multi dotscience/test_dotscience.py::test_run_basics dotscience/test_dotscience.py::test_output_n dotscience/test_dotscience.py::test_output_1a dotscience/test_dotscience.py::test_run_start_1 dotscience/test_dotscience.py::test_start_end dotscience/test_dotscience.py::test_run_start_2 dotscience/test_dotscience.py::test_summary_1b dotscience/test_dotscience.py::test_description_a dotscience/test_dotscience.py::test_non_conflicting_mode_2 dotscience/test_dotscience.py::test_description_c dotscience/test_dotscience.py::test_conflicting_mode_1 dotscience/test_dotscience.py::test_parameter_1b dotscience/test_dotscience.py::test_run_end_1 dotscience/test_dotscience.py::test_run_input_recursive dotscience/test_dotscience.py::test_run_output_1 dotscience/test_dotscience.py::test_run_labels_1 dotscience/test_dotscience.py::test_run_labels_multi dotscience/test_dotscience.py::test_run_input_1 dotscience/test_dotscience.py::test_run_output_n dotscience/test_dotscience.py::test_error_b dotscience/test_dotscience.py::test_label_1b dotscience/test_dotscience.py::test_input_1a dotscience/test_dotscience.py::test_run_null dotscience/test_dotscience.py::test_multi_publish_1 dotscience/test_dotscience.py::test_output_1b dotscience/test_dotscience.py::test_error_a dotscience/test_dotscience.py::test_no_script_name_when_interactive dotscience/test_dotscience.py::test_label_n dotscience/test_dotscience.py::test_summary_n dotscience/test_dotscience.py::test_run_output_relative dotscience/test_dotscience.py::test_no_mode dotscience/test_dotscience.py::test_input_n dotscience/test_dotscience.py::test_run_tensorflow_model dotscience/test_dotscience.py::test_null dotscience/test_dotscience.py::test_run_end_2 dotscience/test_dotscience.py::test_non_conflicting_mode_1 dotscience/test_dotscience.py::test_run_output_recursive dotscience/test_dotscience.py::test_run_tensorflow_model_with_classes dotscience/test_dotscience.py::test_run_parameter_multi dotscience/test_dotscience.py::test_description_b