Uploadthing: Type-error when sending custom field data to the client

So i want to send some data down to the client upon image upload. api/uploadthing.core.ts
.onUploadComplete(async ({ metadata, file }) => {
const commonFileName = file.name.split(".")[0];
const commonFileType = file.name.split(".")[1];

// 1. Fetch the original image which is uploaded
const responseImage = await fetch(file.url);

// 2. Error check
if (!responseImage.ok) new UploadThingError("Failed to fetch image");

// 3. Create a buffer of the original image
const bufferImage = await responseImage.arrayBuffer();

// 4. Make mobile & tablet resized buffers using sharp
const mobileBuffer = await sharp(bufferImage).resize(400, 400).toBuffer();
const tabletBuffer = await sharp(bufferImage).resize(600, 600).toBuffer();

// 5. Create uploadthing files using the buffers
const mobileImage = new UTFile(
[mobileBuffer],
`${commonFileName}/mobile.${commonFileType}`,
);
const tabletImage = new UTFile(
[tabletBuffer],
`${commonFileName}/tablet.${commonFileType}`,
);

// 6. Upload the files
const savedImages = await utapi.uploadFiles([mobileImage, tabletImage]);

// 7. ::Check:: If the images were uploaded successfully
if (!savedImages[0]?.data) {
new UploadThingError("Failed to fetch image");
}

// 8. Create an array of the images with the fields that are to be used in the frontend
const imagesArr: {
key: string;
url: string;
}[] = savedImages
.map((obj) => {
if (obj.data) {
return {
key: obj.data.key,
url: obj.data.url,
};
}
})
.filter((obj) => obj !== undefined);

// 9. Return data to the frontend
return {
metadata: { uploadedBy: metadata.userId, images: [...imagesArr] },
};
}),
.onUploadComplete(async ({ metadata, file }) => {
const commonFileName = file.name.split(".")[0];
const commonFileType = file.name.split(".")[1];

// 1. Fetch the original image which is uploaded
const responseImage = await fetch(file.url);

// 2. Error check
if (!responseImage.ok) new UploadThingError("Failed to fetch image");

// 3. Create a buffer of the original image
const bufferImage = await responseImage.arrayBuffer();

// 4. Make mobile & tablet resized buffers using sharp
const mobileBuffer = await sharp(bufferImage).resize(400, 400).toBuffer();
const tabletBuffer = await sharp(bufferImage).resize(600, 600).toBuffer();

// 5. Create uploadthing files using the buffers
const mobileImage = new UTFile(
[mobileBuffer],
`${commonFileName}/mobile.${commonFileType}`,
);
const tabletImage = new UTFile(
[tabletBuffer],
`${commonFileName}/tablet.${commonFileType}`,
);

// 6. Upload the files
const savedImages = await utapi.uploadFiles([mobileImage, tabletImage]);

// 7. ::Check:: If the images were uploaded successfully
if (!savedImages[0]?.data) {
new UploadThingError("Failed to fetch image");
}

// 8. Create an array of the images with the fields that are to be used in the frontend
const imagesArr: {
key: string;
url: string;
}[] = savedImages
.map((obj) => {
if (obj.data) {
return {
key: obj.data.key,
url: obj.data.url,
};
}
})
.filter((obj) => obj !== undefined);

// 9. Return data to the frontend
return {
metadata: { uploadedBy: metadata.userId, images: [...imagesArr] },
};
}),
type-error
Argument of type '({ metadata, file }: AdapterArgs & { metadata: { userId: string; images: { key: string; url: string; }[]; }; file: UploadedFileData; }) => Promise<{ metadata: { uploadedBy: string; images: { ...; }[]; }; }>' is not assignable to parameter of type 'UploadCompleteFn<{ userId: string; images: { key: string; url: string; }[]; }, void | JsonObject, AdapterArgs>'.
Type 'Promise<{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }>' is not assignable to type 'MaybePromise<void | JsonObject>'.
Type 'Promise<{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }>' is not assignable to type 'Promise<void | JsonObject>'.
Type '{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }' is not assignable to type 'void | JsonObject'.
Type '{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }' is not assignable to type 'JsonObject'.
Property 'metadata' is incompatible with index signature.
Type '{ uploadedBy: string; images: { key: string; url: string; }[]; }' is not assignable to type 'JsonValue | JsonObject | JsonArray'.
Type '{ uploadedBy: string; images: { key: string; url: string; }[]; }' is not assignable to type 'JsonObject'.
Property 'images' is incompatible with index signature.
Type '{ key: string; url: string; }[]' is not assignable to type 'JsonValue | JsonObject | JsonArray'.
Type '{ key: string; url: string; }[]' is not assignable to type 'JsonArray'.
Type '{ key: string; url: string; }' is not assignable to type 'JsonValue'.ts(2345)
Argument of type '({ metadata, file }: AdapterArgs & { metadata: { userId: string; images: { key: string; url: string; }[]; }; file: UploadedFileData; }) => Promise<{ metadata: { uploadedBy: string; images: { ...; }[]; }; }>' is not assignable to parameter of type 'UploadCompleteFn<{ userId: string; images: { key: string; url: string; }[]; }, void | JsonObject, AdapterArgs>'.
Type 'Promise<{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }>' is not assignable to type 'MaybePromise<void | JsonObject>'.
Type 'Promise<{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }>' is not assignable to type 'Promise<void | JsonObject>'.
Type '{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }' is not assignable to type 'void | JsonObject'.
Type '{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }' is not assignable to type 'JsonObject'.
Property 'metadata' is incompatible with index signature.
Type '{ uploadedBy: string; images: { key: string; url: string; }[]; }' is not assignable to type 'JsonValue | JsonObject | JsonArray'.
Type '{ uploadedBy: string; images: { key: string; url: string; }[]; }' is not assignable to type 'JsonObject'.
Property 'images' is incompatible with index signature.
Type '{ key: string; url: string; }[]' is not assignable to type 'JsonValue | JsonObject | JsonArray'.
Type '{ key: string; url: string; }[]' is not assignable to type 'JsonArray'.
Type '{ key: string; url: string; }' is not assignable to type 'JsonValue'.ts(2345)
The imagesArr is what i want on the client as I loop over imagesArr to render all the images. [Important Point]: In the backend all the images are uploaded successfully and in the right size as well -------------
Nextjs 15
App router
tRPC
Nextjs 15
App router
tRPC
8 Replies
webdevkaleem
webdevkaleemOP2w ago
In simple terms i want to send additional content in onUploadComplete and use it onClientUploadComplete but it gives me a type-error when i do so. It only allows this to be returned without any errors
return {
uploadedBy: metadata.userId
}
return {
uploadedBy: metadata.userId
}
markr
markr2w ago
Can you confirm which uploadthing package versions you are using?
webdevkaleem
webdevkaleemOP2w ago
"uploadthing": "^7.4.4", "@uploadthing/react": "^7.1.5",
webdevkaleem
webdevkaleemOP2w ago
thanks for the solution but i guess i have to wait until these changes are reviewed and merged https://github.com/pingdotgg/uploadthing/pull/1115
GitHub
chore(release): 📦 version packages by t3dotgg · Pull Request #1115...
This PR was opened by the Changesets release GitHub action. When you&#39;re ready to do a release, you can merge this and the packages will be published to npm automatically. If you&#39;re ...
markr
markr2w ago
There is a pkg.pr that you can use in the interim: https://github.com/pingdotgg/uploadthing/pull/1127#issuecomment-2584085766
GitHub
fix: allow nested objects in JsonArray type by juliusmarminge · P...
Summary by CodeRabbit New Features Enhanced JSON array handling to support deeply nested objects Expanded test coverage for complex data structures in upload functionality Bug Fixes Patched ...
markr
markr2w ago
I’ll probably cut the release no later than Monday though
webdevkaleem
webdevkaleemOP2w ago
thank you i just got out of tutorial hell (or atleast trying to) so everything is new to me

Did you find this page helpful?