N
Novu2mo ago
r2d2

422 Unprocessable Entity When Sending Attachments via Novu API

@Pawan Jain Description When executing a job in the Novu queue, I encounter a 500 Internal Server Error with an UnknownBridgeRequestError message. The error occurs when Novu tries to call a bridge request to http://api.novu.local:3000/v1/environments/{ENV_ID}/bridge.
await novu.trigger('assessment-results', {
to: {
subscriberId: '123456',
},
payload: {
studentName: 'John Doe',
assessmentDate: 'March 11',
oldEnglishLevel: 'B1+',
newEnglishLevel: 'B2-',
goodFeedback: 'Excellent use of verb tenses',
toImproveFeedback: 'Pronunciation and vocabulary',
attachments: [
{
file: certificateBuffer,
name: 'certificate.pdf',
mime: 'application/pdf',
},
],
},
});
await novu.trigger('assessment-results', {
to: {
subscriberId: '123456',
},
payload: {
studentName: 'John Doe',
assessmentDate: 'March 11',
oldEnglishLevel: 'B1+',
newEnglishLevel: 'B2-',
goodFeedback: 'Excellent use of verb tenses',
toImproveFeedback: 'Pronunciation and vocabulary',
attachments: [
{
file: certificateBuffer,
name: 'certificate.pdf',
mime: 'application/pdf',
},
],
},
});
The job enters the queue but fails to execute with the following error:
{
"url": "http://api.novu.local:3000/v1/environments/67b760905c73e5e854203937/bridge",
"statusCode": 500,
"message": "Unknown bridge request error calling `http://api.novu.local:3000/v1/environments/67b760905c73e5e854203937/bridge`",
"code": "UnknownBridgeRequestError",
"cause": {
"name": "HTTPError",
"code": "ERR_NON_2XX_3XX_RESPONSE",
"timings": {
"start": 1742399460159,
"socket": 1742399460161,
"lookup": 1742399460161,
"connect": 1742399460161,
"upload": 1742399460164,
"response": 1742399460174,
"end": 1742399460174,
"phases": {
"wait": 2,
"dns": 0,
"tcp": 0,
"request": 3,
"firstByte": 10,
"download": 0,
"total": 15
}
}
}
}
{
"url": "http://api.novu.local:3000/v1/environments/67b760905c73e5e854203937/bridge",
"statusCode": 500,
"message": "Unknown bridge request error calling `http://api.novu.local:3000/v1/environments/67b760905c73e5e854203937/bridge`",
"code": "UnknownBridgeRequestError",
"cause": {
"name": "HTTPError",
"code": "ERR_NON_2XX_3XX_RESPONSE",
"timings": {
"start": 1742399460159,
"socket": 1742399460161,
"lookup": 1742399460161,
"connect": 1742399460161,
"upload": 1742399460164,
"response": 1742399460174,
"end": 1742399460174,
"phases": {
"wait": 2,
"dns": 0,
"tcp": 0,
"request": 3,
"firstByte": 10,
"download": 0,
"total": 15
}
}
}
}
No description
16 Replies
Pawan Jain
Pawan Jain2mo ago
@r2d2 Looking into this
r2d2
r2d2OP2mo ago
Thanks, fyi, I tried the docs example (with base64 image example) and it worked... so I don't know if its a file type or a file size issue.
Pawan Jain
Pawan Jain2mo ago
it could be a file format issue. is it valid buffer format? can you share the code example? Can you share the filesize?
r2d2
r2d2OP2mo ago
This is my code:
const certificateBuffer = await this.certificateService.generateCertificate(
'John Good,
'B2-',
);

await this.integrationService.sendEmail(
'progress-assessment-result',
{
subscriberId: '123456',
},
{
studentName: 'John',
assessmentDate: '11 de marzo',
oldEnglishLevel: 'B1+',
newEnglishLevel: 'B2-',
goodFeedback: 'Good',
toImproveFeedback: 'Bad',
attachments: [
{
file: certificateBuffer,
name: 'certificate.pdf',
mime: 'application/pdf',
},
],
},
);
const certificateBuffer = await this.certificateService.generateCertificate(
'John Good,
'B2-',
);

await this.integrationService.sendEmail(
'progress-assessment-result',
{
subscriberId: '123456',
},
{
studentName: 'John',
assessmentDate: '11 de marzo',
oldEnglishLevel: 'B1+',
newEnglishLevel: 'B2-',
goodFeedback: 'Good',
toImproveFeedback: 'Bad',
attachments: [
{
file: certificateBuffer,
name: 'certificate.pdf',
mime: 'application/pdf',
},
],
},
);
The file size range from 200 kB to 300 kB
Pawan Jain
Pawan Jain2mo ago
I am more interested in internals of
const certificateBuffer = await this.certificateService.generateCertificate(
'John Good,
'B2-',
);
const certificateBuffer = await this.certificateService.generateCertificate(
'John Good,
'B2-',
);
r2d2
r2d2OP2mo ago
I'm using pdfkit, and this is my code:
generateCertificate(name: string, level: string): Promise<Buffer> {
const date = this.getCurrentDate();
this.addBackgroundImage();
this.addCertificateText(name, date, level);
this.doc.end();

return this.getPdfBuffer();
}

getPdfBuffer(): Promise<Buffer> {
return new Promise<Buffer>((resolve, reject) => {
this.doc.on('end', () => {
const pdfBuffer = Buffer.concat(this.buffers);
resolve(pdfBuffer);
});
this.doc.on('error', reject);
});
generateCertificate(name: string, level: string): Promise<Buffer> {
const date = this.getCurrentDate();
this.addBackgroundImage();
this.addCertificateText(name, date, level);
this.doc.end();

return this.getPdfBuffer();
}

getPdfBuffer(): Promise<Buffer> {
return new Promise<Buffer>((resolve, reject) => {
this.doc.on('end', () => {
const pdfBuffer = Buffer.concat(this.buffers);
resolve(pdfBuffer);
});
this.doc.on('error', reject);
});
Pawan Jain
Pawan Jain2mo ago
thanks for sharing. I will deep dive into this later today. Want to check if base64 format will work for your usecase?
r2d2
r2d2OP2mo ago
I've tried but file type does not allow me to use a string value:
export interface IAttachmentOptions {
mime: string;
file: Buffer;
name?: string;
channels?: ChannelTypeEnum[];
cid?: string;
disposition?: string;
}
export interface IAttachmentOptions {
mime: string;
file: Buffer;
name?: string;
channels?: ChannelTypeEnum[];
cid?: string;
disposition?: string;
}
I remove my typing restrictions and tried base64, but had the same 500 error.
Novu_Bot
Novu_Bot2mo ago
@r2d2, you just advanced to level 1!
r2d2
r2d2OP2mo ago
async sendAssessmentsResultNotifications() {
const certificateBuffer = await this.certificateService.generateCertificate(
'John,
'B2-',
);
const certificateBase64 = certificateBuffer.toString('base64');

await this.integrationService.sendEmail(
'progress-assessment-result',
{
subscriberId: '123456',
},
{
studentName: 'John',
assessmentDate: '11 de marzo',
oldEnglishLevel: 'B1+',
newEnglishLevel: 'B2-',
goodFeedback: 'Excelente uso de los tiempos verbales',
toImproveFeedback: 'Pronunciación y vocabulario',
attachments: [
{
file: certificateBase64,
name: 'certificate.pdf',
mime: 'application/pdf',
},
],
},
);
}
async sendAssessmentsResultNotifications() {
const certificateBuffer = await this.certificateService.generateCertificate(
'John,
'B2-',
);
const certificateBase64 = certificateBuffer.toString('base64');

await this.integrationService.sendEmail(
'progress-assessment-result',
{
subscriberId: '123456',
},
{
studentName: 'John',
assessmentDate: '11 de marzo',
oldEnglishLevel: 'B1+',
newEnglishLevel: 'B2-',
goodFeedback: 'Excelente uso de los tiempos verbales',
toImproveFeedback: 'Pronunciación y vocabulario',
attachments: [
{
file: certificateBase64,
name: 'certificate.pdf',
mime: 'application/pdf',
},
],
},
);
}
Pawan Jain
Pawan Jain2mo ago
earlier you mentioned that base64 worked
r2d2
r2d2OP2mo ago
Yes with this example:
import { Novu } from '@novu/node';

const novu = new Novu('<NOVU_SECRET_KEY>');

novu.trigger('<WORKFLOW_TRIGGER_IDENTIFIER>', {
to: {
subscriberId: '<SUBSCRIBER_ID>',
},
payload: {
attachments: [
{
// base64 format
file: 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mNkYPhfz0AEYBxVSF+FAP5FDvcfRYWgAAAAAElFTkSuQmCC',
name: 'blue.png',
mime: 'image/png',
}
],
},
});
import { Novu } from '@novu/node';

const novu = new Novu('<NOVU_SECRET_KEY>');

novu.trigger('<WORKFLOW_TRIGGER_IDENTIFIER>', {
to: {
subscriberId: '<SUBSCRIBER_ID>',
},
payload: {
attachments: [
{
// base64 format
file: 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mNkYPhfz0AEYBxVSF+FAP5FDvcfRYWgAAAAAElFTkSuQmCC',
name: 'blue.png',
mime: 'image/png',
}
],
},
});
Just now I was checking and the error it gives is from the bridge point, I have it as local studio, could this have something to do with it? Do I need to do something additional? Another idea, is that the payload has a maximum length and my file is exceeding it? @Pawan Jain @Support Hi, is there any progress or solution for my attachment problem? I have already tried even with the base64 string of my document, calculated separately, and it still throws me an error. I was checking that the errors always fail in step 3, of the connection to the bridge, but already that is going beyond what I understand of how Novu works.
r2d2
r2d2OP5w ago
@Support I keep getting the error from the attached pdf in base64. I am trying directly on the web platform and still get a bridge connection error. I have encoded the pdf on an online site and it weighs 56 kB, and I have been able to decode it, so it is not a problem with my file. I need urgent help with this issue or at least tell me you can't support this and I will look for another solution to Novu.
Pawan Jain
Pawan Jain5w ago
@r2d2 Apologies for missing this. I am checking this on priority @r2d2 I am able to reproduce the issue. Sharing with our team to take a look. I will keep you updated
Linear
Linear5w ago
Found issue NV-5635.
Pawan Jain
Pawan Jain2d ago
@r2d2 This issue is now fixed. Could you please check from your end? @r2d2 Just want to follow up, did you get chance to check on this again? Happy to hear your feedback or any issue you are facing Closing this post due to inactivity. Feel free to create a new one if you still have any questions

Did you find this page helpful?