diff --git a/scipost_django/journals/models/publication.py b/scipost_django/journals/models/publication.py
index 6ee178057277b07efe3a0e5dcc8b0a2690911d9b..5ef34f4d994a7b89bb5a7d4d74a371ace71d8653 100644
--- a/scipost_django/journals/models/publication.py
+++ b/scipost_django/journals/models/publication.py
@@ -5,12 +5,14 @@ __license__ = "AGPL v3"
 from decimal import Decimal
 from string import Template as string_Template
 import re
+from typing import TYPE_CHECKING
 
 from django.contrib.postgres.fields import ArrayField
 from django.core.exceptions import ValidationError
 from django.db import models
 from django.db.models import Min, Sum
 from django.urls import reverse
+from django.utils.functional import cached_property
 
 from ..constants import (
     STATUS_DRAFT,
@@ -31,6 +33,10 @@ from scipost.constants import SCIPOST_APPROACHES
 from scipost.fields import ChoiceArrayField
 
 
+if TYPE_CHECKING:
+    from production.models import ProofsRepository
+
+
 class PublicationAuthorsTable(models.Model):
     """
     PublicationAuthorsTable represents an author of a Publication.
@@ -67,7 +73,7 @@ class PublicationAuthorsTable(models.Model):
     def is_empty(self) -> bool:
         """Check if object is a temporary placeholder."""
         return self.profile is None
-    
+
     @property
     def is_registered(self) -> bool:
         """Check if author is registered at SciPost."""
@@ -476,7 +482,7 @@ class Publication(models.Model):
         return self.pubfracs.aggregate(Sum("fraction"))["fraction__sum"] == 1
     
     @property
-    def proofs_repository(self):
+    def proofs_repository(self) -> "ProofsRepository":
         """Return the proofs repository for the publication."""
         return self.accepted_submission.production_stream.proofs_repository
 
@@ -606,14 +612,29 @@ class Publication(models.Model):
         This list is used to render the affiliation list in the add_author view.
         """
 
-        tex_contents = self.proofs_repository.fetch_publication_tex()
-        return Publication.extract_affiliations_from_tex(tex_contents)
+        if self.tex_contents:
+            return Publication.extract_affiliations_from_tex(self.tex_contents)
+        return []
+
+    @cached_property
+    def tex_contents(self) -> str | None:
+        return self.proofs_repository.fetch_tex()
 
     def construct_tex_author_info(self) -> tuple[list[str], list[list[int]]]:
-        """ Puts together information for each author from the TeX file of the publication. """
-        
-        tex_contents = self.proofs_repository.fetch_publication_tex()
-        author_field = re.findall("%%%%%%%%%% TODO: AUTHORS(.*?)%%%%%%%%%% END TODO: AUTHORS", tex_contents, re.DOTALL)[0]
+        """Puts together information for each author from the TeX file of the publication."""
+
+        tex_contents = self.tex_contents or ""
+        author_field_match = re.search(
+            "%%%%%%%%%% TODO: AUTHORS(.*?)%%%%%%%%%% END TODO: AUTHORS",
+            tex_contents,
+            re.DOTALL,
+        )
+        if author_field_match is None:
+            # If matching against the tex file fails, we use the author_list of the submission.
+            original_authors_as_list = [author.strip() for author in self.author_list.split(",")]
+            return original_authors_as_list, [[] for _ in original_authors_as_list]
+        else:
+            author_field = author_field_match.group(1)
         author_texts = author_field.strip().replace("\,", "").split("\n")
 
         # Remove any trailing or leading "and"s.
diff --git a/scipost_django/journals/views.py b/scipost_django/journals/views.py
index 94feb2d5bd21bf9f5d35983df15548ba48320a1c..6f712561fb8436845534e5b36214ca5f79c514a4 100644
--- a/scipost_django/journals/views.py
+++ b/scipost_django/journals/views.py
@@ -987,8 +987,9 @@ def add_author(request, doi_label: str) -> HttpResponse:
     )
 
     # Update and save the author_list in the publication object.
-    publication.author_list = ", ".join(author_string_list)
-    publication.save()
+    if len(author_string_list) > 0:
+        publication.author_list = ", ".join(author_string_list)
+        publication.save()
 
     context = {
         "publication": publication,
diff --git a/scipost_django/production/models.py b/scipost_django/production/models.py
index 48ce75866e657de11c0e8a4a04c16677ec0b6f32..ae05406e9a7eb2c40cc24496d0a7c24b7380a712 100644
--- a/scipost_django/production/models.py
+++ b/scipost_django/production/models.py
@@ -536,19 +536,54 @@ class ProofsRepository(models.Model):
 
         return paths
 
-    def fetch_publication_tex(self) -> str:
-        """ Fetches the TeX file of the publication. """
-        gl = gitlab.Gitlab("https://" + settings.GITLAB_URL, private_token = settings.GITLAB_KEY)
-        gl.auth()
-        
-        project = gl.projects.get(self.git_path)
+    def fetch_tex(self) -> str | None:
+        """
+        Fetches the TeX file of the publication, or of the proofs if not available.
+        If both fail, returns None.
+        """
+        # Attempt to authenticate with GitLab
+        try:
+            gl = gitlab.Gitlab(
+                "https://" + settings.GITLAB_URL,
+                private_token=settings.GITLAB_KEY,
+            )
+            gl.auth()
+        except:
+            return None
+
         publication: "Publication" = self.stream.submission.publications.first()
-        
-        main_file_path = publication.doi_label.replace(".", "_") +".tex"
-        publication_file = project.files.get(file_path = main_file_path, ref = "main")
-        tex_contents = publication_file.decode().decode("utf-8")
-        
-        return tex_contents
+        publication_filename = publication.doi_label.replace(".", "_") + ".tex"
+
+        # Attempt to fetch the project from GitLab
+        try:
+            project = gl.projects.get(self.git_path)
+        except:
+            return None
+
+        # Attempt to fetch the publication file
+        try:
+            publication_file = project.files.get(
+                file_path=publication_filename, ref="main"
+            )
+            tex_contents = publication_file.decode().decode("utf-8")
+            return tex_contents
+        except:
+            pass
+
+        # Fall back to the submission's main file
+        proofs_file = None
+        for project_file in project.repository_tree(ref="main"):
+            project_filename = project_file["name"]
+            if project_filename.endswith(".tex") and self.name in project_filename:
+                proofs_file = project.files.get(file_path=project_filename, ref="main")
+                break
+
+        if proofs_file is not None:
+            tex_contents = proofs_file.decode().decode("utf-8")
+            return tex_contents
+
+        # If all else fails, return None
+        return None
 
     def __str__(self) -> str:
         return f"Proofs repo for {self.stream}"