Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ describe("validatePayload", () => {
};
expect(() => validatePayload(invalidPayload)).toThrow(ValidationError);
expect(() => validatePayload(invalidPayload)).toThrow(
"Invalid message configuration: Field 'message.attachments' must be an array"
"Invalid message configuration: Field 'message.attachments' must be an array. If you have a single attachment object, wrap it in an array (e.g., [{ filename: '...', path: '...' }])"
);
});
});
Expand Down
16 changes: 15 additions & 1 deletion firestore-send-email/functions/src/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ export const attachmentSchema = z
});

export const attachmentsSchema = z
.array(attachmentSchema)
.array(attachmentSchema, {
invalid_type_error:
Comment thread
cabljac marked this conversation as resolved.
"Field 'attachments' must be an array. If you have a single attachment object, wrap it in an array (e.g., [{ filename: '...', path: '...' }])",
})
.optional()
.transform((attachments) =>
attachments
Expand Down Expand Up @@ -182,10 +185,21 @@ function formatZodError(
const path = issue.path.length > 0 ? issue.path.join(".") : context;
switch (issue.code) {
case "invalid_type":
if (issue.received === "undefined") {
return `Field '${path}' must be a ${issue.expected}`;
}

Copy link
Copy Markdown
Contributor

@cabljac cabljac Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually i think a cleaner fix is I think in here we need

case "invalid_type":
  
  // Missing required field (received undefined)
  if (issue.received === "undefined") {
    return `Field '${path}' must be a ${issue.expected}`;
  }

  // Type mismatch cases
  if (issue.expected === "string") {
    return `Field '${path}' must be a string`;
  }
  if (issue.expected === "array") {
    return `Field '${path}' must be an array`;
  }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@HassanBahati did you push changes taking this approach? i dont see them

if (issue.expected === "string") {
return `Field '${path}' must be a string`;
}
if (issue.expected === "array") {
if (issue.message && !issue.message.startsWith("Expected")) {
const customMessage = issue.message.replace(
/Field 'attachments'/g,
`Field '${path}'`
);
return customMessage;
}
return `Field '${path}' must be an array`;
}
if (issue.expected === "object") {
Expand Down
Loading