diff --git a/blender_manifest.toml b/blender_manifest.toml
index 3867861..92c19ec 100644
--- a/blender_manifest.toml
+++ b/blender_manifest.toml
@@ -3,7 +3,7 @@ schema_version = "1.0.0"
 # Example of manifest file for a Blender extension
 # Change the values according to your extension
 id = "sequence_loader"
-version = "0.3.3"
+version = "0.3.4"
 name = "Blender Sequence Loader"
 tagline = "Just-in-time loader for meshio-supported mesh file sequences"
 maintainer = "Stefan Rhys Jeske <contact@srjeske.de>"
diff --git a/bseq/callback.py b/bseq/callback.py
index 6aaff62..079b702 100644
--- a/bseq/callback.py
+++ b/bseq/callback.py
@@ -1,30 +1,36 @@
 import bpy
 import fileseq
+import traceback
+
+from .utils import show_message_box
 
 #  Code here are mostly about the callback/update/items functions used in properties.py
 
 file_sequences = []
 
 def update_path(self, context):
+    '''
+    Detects all the file sequences in the directory
+    '''
+
     # When the path has been changed, reset the selected sequence to None
     context.scene.BSEQ['fileseq'] = 1
     context.scene.BSEQ.use_pattern = False
     context.scene.BSEQ.pattern = ""
-
-    '''
-    Detects all the file sequences in the directory
-    '''
+    file_sequences.clear()
     
     p = context.scene.BSEQ.path
     try:
-        f = fileseq.findSequencesOnDisk(p)
-    except:
-        return [("None", "No sequence detected", "", 1)]
+        f = fileseq.findSequencesOnDisk(bpy.path.abspath(p))
+    except Exception as e:
+        show_message_box("Error when reading path\n" + traceback.format_exc(),
+                         "fileseq Error" + str(e),
+                         icon="ERROR")
+        return None
 
     if not f:
-        return [("None", "No sequence detected", "", 1)]
+        return None
 
-    file_sequences.clear()
     if len(f) >= 30:
         file_sequences.append(("None", "Too much sequence detected, could be false detection, please use pattern below", "", 1))
     else:
diff --git a/bseq/importer.py b/bseq/importer.py
index 73b1d01..523b6f7 100644
--- a/bseq/importer.py
+++ b/bseq/importer.py
@@ -162,7 +162,7 @@ def update_mesh(meshio_mesh, mesh):
     else:
         mesh.clear_geometry()
         mesh.vertices.add(n_verts)
-        mesh.edges.add(len(edge_data))
+        mesh.edges.add(len(edges))
         mesh.loops.add(n_loop)
         mesh.polygons.add(n_poly)
 
@@ -204,7 +204,7 @@ def update_mesh(meshio_mesh, mesh):
 
         # set as split normal per vertex
         if mesh.BSEQ.split_norm_att_name and mesh.BSEQ.split_norm_att_name == k:
-            # If blender version is less than 4.1.0, then dont set auto smooth.
+            # If blender version is greater than 4.1.0, then don't set auto smooth.
             # It has been removed and normals will be used automatically if they are set.
             # https://developer.blender.org/docs/release_notes/4.1/python_api/#mesh
             if bpy.app.version < (4, 1, 0):
@@ -217,8 +217,9 @@ def update_mesh(meshio_mesh, mesh):
         
         # set split normal per loop per vertex
         if mesh.BSEQ.split_norm_att_name and mesh.BSEQ.split_norm_att_name == k:
-            # Currently hard-coded for .obj files
-            mesh.use_auto_smooth = True
+            if bpy.app.version < (4, 1, 0):
+                mesh.use_auto_smooth = True
+            # currently hard-coded for .obj files
             indices = [item for sublist in meshio_mesh.cell_data["obj:vn_face_idx"][0] for item in sublist]
             mesh.normals_split_custom_set([meshio_mesh.field_data["obj:vn"][i - 1] for i in indices])
 
@@ -261,13 +262,14 @@ def create_obj(fileseq, use_relative, root_path, transform_matrix=Matrix.Identit
     object = bpy.data.objects.new(name, mesh)
 
     #  create the object
+    full_path = str(fileseq)
+    path = os.path.dirname(full_path)
+    pattern = os.path.basename(full_path)
     if use_relative:
-        full_path = get_relative_path(str(fileseq), root_path)
-    else:
-        full_path = str(fileseq)
+        path = get_relative_path(path, root_path)
     # path is only the directory in which the file is located
-    object.BSEQ.path = os.path.dirname(full_path)
-    object.BSEQ.pattern = os.path.basename(full_path)
+    object.BSEQ.path = path
+    object.BSEQ.pattern = pattern
     object.BSEQ.current_file = filepath
     object.BSEQ.init = True
     object.BSEQ.enabled = enabled
diff --git a/bseq/operators.py b/bseq/operators.py
index 5028048..7168868 100644
--- a/bseq/operators.py
+++ b/bseq/operators.py
@@ -50,7 +50,8 @@ def execute(self, context):
             fs = importer_prop.path + '/' + importer_prop.pattern
 
         try:
-            fs = fileseq.findSequenceOnDisk(fs)
+            # Call os.path.abspath in addition because findSequenceOnDisk does not support \..\ components on Windows apparently
+            fs = fileseq.findSequenceOnDisk(os.path.abspath(bpy.path.abspath(fs)))
         except Exception as e:
             show_message_box(traceback.format_exc(), "Can't find sequence: " + str(fs), "ERROR")
             return {"CANCELLED"}
@@ -522,7 +523,7 @@ def execute(self, context):
         return {'FINISHED'}
     
 class BSEQ_OT_load_all(bpy.types.Operator):
-    """Load all sequences from selected folder"""
+    """Load all sequences from selected folder and its subfolders"""
     bl_idname = "bseq.load_all"
     bl_label = "Load All"
     bl_options = {'PRESET', 'UNDO'}
@@ -533,8 +534,8 @@ def execute(self, context):
         if importer_prop.use_relative and not bpy.data.is_saved:
             return relative_path_error()
 
-        dir = importer_prop.path
-        seqs = fileseq.findSequencesOnDisk(str(dir))
+        p = importer_prop.path
+        seqs = fileseq.findSequencesOnDisk(bpy.path.abspath(p))
 
         for s in seqs:
             print(s)
@@ -555,60 +556,56 @@ def execute(self, context):
         if importer_prop.use_relative and not bpy.data.is_saved:
             return relative_path_error()
 
-        root_dir = importer_prop.path
+        root_dir = bpy.path.abspath(importer_prop.path)
         root_coll = bpy.context.scene.collection
         root_layer_collection = bpy.context.view_layer.layer_collection
         unlinked_collections = []
-        # Recurse through subdirectories
-        for root, dirs, files in os.walk(bpy.path.abspath(root_dir)):
-            for dir in sorted(dirs):
-                # Process subdirectory
-                subdirectory = os.path.join(root, dir)
-
-                seqs = fileseq.findSequencesOnDisk(subdirectory)
-                if len(seqs) == 0:
-                    continue
-
-                # Get list of directories from the root_dir to the current subdirectory
-                coll_list = bpy.path.relpath(subdirectory, start=root_dir).strip("//").split("/")
-
-                # Get or create a nested collection starting from the root
-                last_coll = root_coll
-                layer_collection = root_layer_collection
-                for coll in coll_list:
-                    # If it already exists and is not in the children of the last collection, then the prefix has changed
-                    cur_coll = bpy.data.collections.get(coll)
-                    if cur_coll is not None and last_coll is not None:
-                        if cur_coll.name not in last_coll.children:
-                            # Get the old parent of the existing collection and move the children to the old parent
-                            parent = [c for c in bpy.data.collections if bpy.context.scene.user_of_id(cur_coll) and cur_coll.name in c.children]
-                            if len(parent) > 0:
-                                for child in cur_coll.children:
-                                    parent[0].children.link(child)
-                                for obj in cur_coll.objects:
-                                    parent[0].objects.link(obj)
-                                parent[0].children.unlink(cur_coll)
-                                unlinked_collections.append(cur_coll)
-                        else:
-                            layer_collection = layer_collection.children[cur_coll.name]
-                            last_coll = cur_coll
-
-
-                    # If it was newly created, link it to the last collection
-                    if cur_coll is None and last_coll is not None:
-                        cur_coll = bpy.data.collections.new(coll)
-                        last_coll.children.link(cur_coll)
+        # Recurse through directory itself and subdirectories
+        for current_dir, subdirs, files in os.walk(root_dir):
+            seqs = fileseq.findSequencesOnDisk(current_dir)
+            if len(seqs) == 0:
+                continue
+
+            # Get list of directories from the root_dir to the current directory
+            coll_list = bpy.path.relpath(current_dir, start=root_dir).strip("//").split("/")
+
+            # Get or create a nested collection starting from the root
+            last_coll = root_coll
+            layer_collection = root_layer_collection
+            for coll in coll_list:
+                # If it already exists and is not in the children of the last collection, then the prefix has changed
+                cur_coll = bpy.data.collections.get(coll)
+                if cur_coll is not None and last_coll is not None:
+                    if cur_coll.name not in last_coll.children:
+                        # Get the old parent of the existing collection and move the children to the old parent
+                        parent = [c for c in bpy.data.collections if bpy.context.scene.user_of_id(cur_coll) and cur_coll.name in c.children]
+                        if len(parent) > 0:
+                            for child in cur_coll.children:
+                                parent[0].children.link(child)
+                            for obj in cur_coll.objects:
+                                parent[0].objects.link(obj)
+                            parent[0].children.unlink(cur_coll)
+                            unlinked_collections.append(cur_coll)
+                    else:
                         layer_collection = layer_collection.children[cur_coll.name]
                         last_coll = cur_coll
 
-                # Set the last collection as the active collection by recursing through the collections
-                context.view_layer.active_layer_collection = layer_collection
 
-                # for s in seqs:
-                #     print(s)
+                # If it was newly created, link it to the last collection
+                if cur_coll is None and last_coll is not None:
+                    cur_coll = bpy.data.collections.new(coll)
+                    last_coll.children.link(cur_coll)
+                    layer_collection = layer_collection.children[cur_coll.name]
+                    last_coll = cur_coll
+
+            # Set the last collection as the active collection by recursing through the collections
+            context.view_layer.active_layer_collection = layer_collection
+
+            # for s in seqs:
+            #     print(s)
 
-                for s in seqs:
-                    create_obj_wrapper(s, importer_prop)
+            for s in seqs:
+                create_obj_wrapper(s, importer_prop)
             
         # Make sure unused datablocks are freed
         for coll in unlinked_collections:
diff --git a/bseq/utils.py b/bseq/utils.py
index 22f5ad2..161542c 100644
--- a/bseq/utils.py
+++ b/bseq/utils.py
@@ -21,7 +21,6 @@ def draw(self, context):
     stop_animation()
     bpy.context.window_manager.popup_menu(draw, title=title, icon=icon)
 
-
 def stop_animation():
     if bpy.context.screen.is_animation_playing:
         #  if playing animation, then stop it, otherwise it will keep showing message box
@@ -29,17 +28,18 @@ def stop_animation():
 
 def get_relative_path(path, root_path):
     if root_path != "":
-        path = bpy.path.relpath(path, start=root_path)
+        rel_path = bpy.path.relpath(path, start=bpy.path.abspath(root_path))
     else:
-        path = bpy.path.relpath(path)    
-    return path
+        rel_path = bpy.path.relpath(path)    
+    return rel_path
 
 # convert relative path to absolute path
 def convert_to_absolute_path(path, root_path):
+    # Additional call to os.path.abspath removes any "/../"" in the path (can be a problem on Windows)
     if root_path != "":
-        path = bpy.path.abspath(path, start=root_path)
+        path = os.path.abspath(bpy.path.abspath(path, start=bpy.path.abspath(root_path)))
     else:
-        path = bpy.path.abspath(path)    
+        path = os.path.abspath(bpy.path.abspath(path))
     return path
 
 def get_absolute_path(obj, scene):
@@ -47,19 +47,21 @@ def get_absolute_path(obj, scene):
     full_path = convert_to_absolute_path(full_path, scene.BSEQ.root_path)
     return full_path
 
-
 def refresh_obj(obj, scene):
     is_relative = obj.BSEQ.path.startswith("//")
-    print("is_relative: ", is_relative)
     fs = get_absolute_path(obj, scene)
     fs = fileseq.findSequenceOnDisk(fs)
-    fs = fileseq.findSequenceOnDisk(fs.dirname() + fs.basename() + "@" + fs.extension())
-    obj.BSEQ.start_end_frame = (fs.start(), fs.end())
-    fs = str(fs)
+    #fs = fileseq.findSequenceOnDisk(fs.dirname() + fs.basename() + "@" + fs.extension())
+
+    full_path = str(fs)
+    path = os.path.dirname(full_path)
+    pattern = os.path.basename(full_path)
     if is_relative:
-        fs = get_relative_path(fs, scene.BSEQ.root_path)
-    obj.BSEQ.path = os.path.dirname(fs)
-    obj.BSEQ.pattern = os.path.basename(fs)
+        path = get_relative_path(path, scene.BSEQ.root_path)
+
+    obj.BSEQ.path = path
+    obj.BSEQ.pattern = pattern
+    obj.BSEQ.start_end_frame = (fs.start(), fs.end())
 
 def load_meshio_from_path(fileseq, filepath, obj = None):
     try:
diff --git a/docs/conf.py b/docs/conf.py
index d81a6a8..d4e3eb7 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -7,9 +7,9 @@
 # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
 
 project = 'blender-sequence-loader'
-copyright = '2024, InteractiveComputerGraphics'
+copyright = '2025, InteractiveComputerGraphics'
 author = 'InteractiveComputerGraphics'
-release = '0.3.3'
+release = '0.3.4'
 
 # -- General configuration ---------------------------------------------------
 # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
