diff --git a/CHANGELOG b/CHANGELOG
index 41dcd4f341f04d06bd53c4b6106f8387082bffaa..113515be6a51e28f6449b7b17cc550f638585a88 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,8 @@
 smasch (1.0.1-1) stable; urgency=low
 
+  * bug fix: generating documents for templates did not work for subjects
+    created before custom field was added to the study (#388)
+
  -- Piotr Gawron <piotr.gawron@uni.lu>  Mon, 15 Mar 2021 14:00:00 +0200
 
 smasch (1.0.0-1) stable; urgency=low
diff --git a/smash/web/docx_helper.py b/smash/web/docx_helper.py
index d8d52829af625780328cb76f61e09d3fa8e306bc..e833eb1f80c401ab18835b6015c2f89e5525242a 100644
--- a/smash/web/docx_helper.py
+++ b/smash/web/docx_helper.py
@@ -26,23 +26,27 @@ def process_file(path_to_docx, path_to_new_docx, changes_to_apply):
 
     doc.save(path_to_new_docx)
 
+
 def merge_files(files, path_to_new_docx):
-    '''
-    When combining templates into a new Document object, python-docx does not properly copy the information of the images, then Word is not able to locate the original content referred by the XML tag in the document. To fix this problem (see #234 ) the first file is loaded and the rest of templates are concatenated to this. This way, the original image content and rId match and the images are shown adequately.
+    """
+    When combining templates into a new Document object, python-docx does not properly copy the information of the
+    images, then Word is not able to locate the original content referred by the XML tag in the document. To fix this
+    problem (see #234 ) the first file is loaded and the rest of templates are concatenated to this. This way, the
+    original image content and rId match and the images are shown adequately.
     See issue #235
-    '''
+    """
     first_file = files[0]
     files = files[1:]
-    merged_document = Document(first_file) #first file
+    merged_document = Document(first_file)  # first file
 
     if len(files) > 0:
         merged_document.add_page_break()
 
-    for index, file in enumerate(files): #rest of files if any
+    for index, file in enumerate(files):  # rest of files if any
         sub_doc = Document(file)
         if index < len(files) - 1:
             sub_doc.add_page_break()
         for element in sub_doc.element.body:
             merged_document.element.body.append(element)
-       
-    merged_document.save(path_to_new_docx)
\ No newline at end of file
+
+    merged_document.save(path_to_new_docx)
diff --git a/smash/web/models/mail_template.py b/smash/web/models/mail_template.py
index 633fbf4dd9c07175b3040ad9db6e54831baef33a..cbc6bf25b19a84afc4fc748ef0f572a904e9338b 100644
--- a/smash/web/models/mail_template.py
+++ b/smash/web/models/mail_template.py
@@ -338,13 +338,13 @@ class MailTemplate(models.Model):
                 "##S_ADDRESS##": study_subject.subject.address,
                 "##S_CITY##": study_subject.subject.city,
                 "##S_COUNTRY##": str(study_subject.subject.country),
-                "##S_DIAGNOSIS_YEAR##": study_subject.get_custom_field_value('Year of diagnosis'),
+                "##S_DIAGNOSIS_YEAR##": str(study_subject.get_custom_field_value('Year of diagnosis')),
                 "##S_DATE_ADDED##": date_to_str(study_subject.date_added, DATE_FORMAT_SHORT),
                 "##S_DATE_BORN##": date_born,
-                "##S_DIAGNOSIS##": study_subject.get_custom_field_value('Diagnosis'),
+                "##S_DIAGNOSIS##": str(study_subject.get_custom_field_value('Diagnosis')),
                 "##S_EMAIL##": str(study_subject.subject.email),
                 "##S_SEX##": study_subject.subject.get_sex_display(),
-                "##S_MPOWER_ID##": study_subject.get_custom_field_value('MPower ID'),
+                "##S_MPOWER_ID##": str(study_subject.get_custom_field_value('MPower ID')),
                 "##S_ND_NUMBER##": study_subject.nd_number,
                 "##S_PHONE_NUMBER##": str(study_subject.subject.phone_number),
                 "##S_PHONE_NUMBER_2##": str(study_subject.subject.phone_number_2),
diff --git a/smash/web/tests/models/test_mail_template.py b/smash/web/tests/models/test_mail_template.py
index e42ca32e9582a2444bd5b51197981e77b7449d35..3c8b4e380afaf7ced5bc1bea644bdbdb15fba9ea 100644
--- a/smash/web/tests/models/test_mail_template.py
+++ b/smash/web/tests/models/test_mail_template.py
@@ -4,13 +4,14 @@ import io
 from django.test import TestCase
 from docx import Document
 
-from web.models import MailTemplate
+from web.models import MailTemplate, StudySubject, Language
 from web.models.constants import MAIL_TEMPLATE_CONTEXT_APPOINTMENT, MAIL_TEMPLATE_CONTEXT_VISIT, \
-    MAIL_TEMPLATE_CONTEXT_SUBJECT, MAIL_TEMPLATE_CONTEXT_VOUCHER
+    MAIL_TEMPLATE_CONTEXT_SUBJECT, MAIL_TEMPLATE_CONTEXT_VOUCHER, CUSTOM_FIELD_TYPE_TEXT
+from web.models.custom_data import CustomStudySubjectField
 from web.models.mail_template import DATE_FORMAT_SHORT
 from web.tests.functions import create_language, get_resource_path, create_appointment, create_user, \
     create_study_subject, \
-    create_visit, create_voucher, create_worker, create_flying_team
+    create_visit, create_voucher, create_worker, create_flying_team, get_test_study
 
 
 class MailTemplateModelTests(TestCase):
@@ -100,19 +101,32 @@ class MailTemplateModelTests(TestCase):
         self.check_doc_contains(doc, [flying_team_name])
 
     def test_apply_subject(self):
-        template_name_french = "test_fr"
         subject = create_study_subject()
-        subject_template_french = MailTemplate(name=template_name_french, language=self.french_language,
-                                               context=MAIL_TEMPLATE_CONTEXT_SUBJECT,
-                                               template_file=self.template_file)
-        stream = io.BytesIO()
-        subject_template_french.apply(subject, self.user, stream)
-        doc = Document(stream)
+        doc = self.create_doc_for_subject(subject, self.french_language, MAIL_TEMPLATE_CONTEXT_SUBJECT)
+        worker_name = str(self.user.worker)
+
+        self.check_doc_contains(doc, [worker_name, str(subject), str(subject.subject.country), subject.nd_number,
+                                      subject.get_type_display()])
+
+    def test_apply_subject_with_non_existing_custom_field(self):
+        subject = create_study_subject()
+        field = CustomStudySubjectField.objects.create(name="Diagnosis", type=CUSTOM_FIELD_TYPE_TEXT,
+                                                       study=get_test_study(), unique=True)
+        doc = self.create_doc_for_subject(subject, self.french_language, MAIL_TEMPLATE_CONTEXT_SUBJECT)
         worker_name = str(self.user.worker)
 
         self.check_doc_contains(doc, [worker_name, str(subject), str(subject.subject.country), subject.nd_number,
                                       subject.get_type_display()])
 
+    def create_doc_for_subject(self, subject: StudySubject, language: Language, context: str):
+        subject_template_french = MailTemplate(name="test_fr", language=language,
+                                               context=context,
+                                               template_file=self.template_file)
+        stream = io.BytesIO()
+        subject_template_french.apply(subject, self.user, stream)
+        doc = Document(stream)
+        return doc
+
     def test_apply_voucher(self):
         template_name_french = "test_without_language"
         subject = create_study_subject()