ExpectedValidatorError on showModal()

When attempting to respond to an interaction via interaction.showModal(), the following error appears:
CombinedPropertyError (1)
Received one or more errors

input[0]
| ExpectedValidationError > s.instance(V)
| Expected
|
| Expected:
| | [Function: ActionRowBuilder]
|
| Received:
| | { data: [Object], components: [Object] }

at _ArrayValidator.handle (D:\code\javascript\discordBots\schedulingBot\node_modules\@sapphire\shapeshift\dist\cjs\index.cjs:1205:70)
at _ArrayValidator.parse (D:\code\javascript\discordBots\schedulingBot\node_modules\@sapphire\shapeshift\dist\cjs\index.cjs:939:90)
at validateRequiredParameters (D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1478:23)
at ModalBuilder (D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1548:5)
at Command_Schedule.replyCreate (file:///D:/code/javascript/discordBots/schedulingBot/build/discordServer/commands/commands/Command_Schedules.js:94:81)
at Command_Schedule.reply (file:///D:/code/javascript/discordBots/schedulingBot/build/discordServer/commands/commands/Command_Schedules.js:61:40)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async DiscordClient.onInteractionCreate (file:///D:/code/javascript/discordBots/schedulingBot/build/discordServer/DiscordClient.js:37:34)
CombinedPropertyError (1)
Received one or more errors

input[0]
| ExpectedValidationError > s.instance(V)
| Expected
|
| Expected:
| | [Function: ActionRowBuilder]
|
| Received:
| | { data: [Object], components: [Object] }

at _ArrayValidator.handle (D:\code\javascript\discordBots\schedulingBot\node_modules\@sapphire\shapeshift\dist\cjs\index.cjs:1205:70)
at _ArrayValidator.parse (D:\code\javascript\discordBots\schedulingBot\node_modules\@sapphire\shapeshift\dist\cjs\index.cjs:939:90)
at validateRequiredParameters (D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1478:23)
at ModalBuilder (D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1548:5)
at Command_Schedule.replyCreate (file:///D:/code/javascript/discordBots/schedulingBot/build/discordServer/commands/commands/Command_Schedules.js:94:81)
at Command_Schedule.reply (file:///D:/code/javascript/discordBots/schedulingBot/build/discordServer/commands/commands/Command_Schedules.js:61:40)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async DiscordClient.onInteractionCreate (file:///D:/code/javascript/discordBots/schedulingBot/build/discordServer/DiscordClient.js:37:34)
15 Replies
d.js toolkit
d.js toolkit11mo ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button!
ierdna100
ierdna100OP11mo ago
Modal in question:
class Modal_ScheduleUpload extends BaseModal {
// prettier-ignore
public modalBuilder = new ModalBuilder()
.setCustomId("schedule_modal")
.setTitle("Input your schedule")
.setComponents(
new ActionRowBuilder<TextInputBuilder>()
.addComponents(new TextInputBuilder()
.setCustomId("username")
.setMaxLength(20)
.setPlaceholder("Display name")
.setRequired(true)
.setLabel("Your display name")
.setStyle(TextInputStyle.Short)))
}
class Modal_ScheduleUpload extends BaseModal {
// prettier-ignore
public modalBuilder = new ModalBuilder()
.setCustomId("schedule_modal")
.setTitle("Input your schedule")
.setComponents(
new ActionRowBuilder<TextInputBuilder>()
.addComponents(new TextInputBuilder()
.setCustomId("username")
.setMaxLength(20)
.setPlaceholder("Display name")
.setRequired(true)
.setLabel("Your display name")
.setStyle(TextInputStyle.Short)))
}
The caller:
try {
await interaction.showModal(new Modal_ScheduleUpload().modalBuilder);
} catch (e) {
console.log(e);
fs.writeFileSync("./debug.json", JSON.stringify(e, null, "\t"));
}
try {
await interaction.showModal(new Modal_ScheduleUpload().modalBuilder);
} catch (e) {
console.log(e);
fs.writeFileSync("./debug.json", JSON.stringify(e, null, "\t"));
}
ive cross checked with the docs a dozen times, my modal looks fine in terms of structure and Im nearly 100% certain a similar modal worked on this same bot
ierdna100
ierdna100OP11mo ago
No description
ierdna100
ierdna100OP11mo ago
I'm sorry? The static initialization is to be able to reference it from other classes, its like this here (individually constructed) to make sure its not the modal loader that's broken It also only contains one component for the same reason (testing only)
import fs from "fs";
import BaseModal from "./Modal_Base.js";

export class ModalLoader {
public static modals: BaseModal[] = [];

public static async loadModals() {
ModalLoader.modals = [];

const modalFilenames = fs.readdirSync("./build/discordServer/commands/modals/");

for (const modalFilename of modalFilenames) {
let modal: { default: new () => BaseModal } = await import(`./modals/${modalFilename}`);
ModalLoader.modals.push(new modal.default());
}
}

public static getModalByCustomId(id: string): BaseModal | undefined {
for (const modal of ModalLoader.modals) {
if (modal.modalBuilder.data.custom_id == id) {
return modal;
}
}

return undefined;
}
}
import fs from "fs";
import BaseModal from "./Modal_Base.js";

export class ModalLoader {
public static modals: BaseModal[] = [];

public static async loadModals() {
ModalLoader.modals = [];

const modalFilenames = fs.readdirSync("./build/discordServer/commands/modals/");

for (const modalFilename of modalFilenames) {
let modal: { default: new () => BaseModal } = await import(`./modals/${modalFilename}`);
ModalLoader.modals.push(new modal.default());
}
}

public static getModalByCustomId(id: string): BaseModal | undefined {
for (const modal of ModalLoader.modals) {
if (modal.modalBuilder.data.custom_id == id) {
return modal;
}
}

return undefined;
}
}
this is usually how I reference it Its also shortened because the whole file itself with the other attached methods is too large for Discord Yes, correct For testing To ensure it wasnt the loader that was broken
ierdna100
ierdna100OP11mo ago
this is what it usually looks like
No description
ierdna100
ierdna100OP11mo ago
Yes
ierdna100
ierdna100OP11mo ago
This is the JS file
No description
ierdna100
ierdna100OP11mo ago
Modal looks okay too
No description
ierdna100
ierdna100OP11mo ago
The rest works, replacing the .showModal() with a .reply() successfully responds Of? The modal or the command reply manager? Sorry, I went to sleep. I've experimented more and now I get a different fun error when I split the modal creation into multiple parts
D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1384
throw new Error(`Cannot properly serialize component type: ${data.type}`);
^

Error: Cannot properly serialize component type: undefined
at createComponentBuilder (D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1384:13)
at D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1434:54
at Array.map (<anonymous>)
at new ActionRowBuilder (D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1434:35)
at D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1530:76
at Array.map (<anonymous>)
at ModalBuilder.addComponents (D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1529:37)
at new Modal_ScheduleUpload (file:///D:/code/javascript/discordBots/schedulingBot/build/discordServer/commands/modals/Modal_UploadSchedule.js:19:118)
at Function.loadModals (file:///D:/code/javascript/discordBots/schedulingBot/build/discordServer/commands/ModalLoader.js:8:37)
PS D:\code\javascript\discordBots\schedulingBot>
D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1384
throw new Error(`Cannot properly serialize component type: ${data.type}`);
^

Error: Cannot properly serialize component type: undefined
at createComponentBuilder (D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1384:13)
at D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1434:54
at Array.map (<anonymous>)
at new ActionRowBuilder (D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1434:35)
at D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1530:76
at Array.map (<anonymous>)
at ModalBuilder.addComponents (D:\code\javascript\discordBots\schedulingBot\node_modules\@discordjs\builders\dist\index.js:1529:37)
at new Modal_ScheduleUpload (file:///D:/code/javascript/discordBots/schedulingBot/build/discordServer/commands/modals/Modal_UploadSchedule.js:19:118)
at Function.loadModals (file:///D:/code/javascript/discordBots/schedulingBot/build/discordServer/commands/ModalLoader.js:8:37)
PS D:\code\javascript\discordBots\schedulingBot>
ierdna100
ierdna100OP11mo ago
This is the modal's file Oh my god youve got to be kidding me Okay I think the definitions for Typescript are bugged Ive managed to get it working, all it required was that the ModalBuilder's .addComponents() takes actionRow.toJSON(), and not the ActionRow itself, although the type checker does think it is correct
ierdna100
ierdna100OP11mo ago
Should I report this as a bug?
No description
ierdna100
ierdna100OP11mo ago
i.e.: This works:
const firstActionRow = new ActionRowBuilder<TextInputBuilder>({
components: [
{
custom_id: "username",
max_length: 20,
placeholder: "Display name",
style: TextInputStyle.Short,
label: "Your display name",
type: ComponentType.TextInput
}
]
});

this.modalBuilder = new ModalBuilder().setCustomId("schedule_builder").setTitle("Input your schedule here!").addComponents(firstActionRow.toJSON());
const firstActionRow = new ActionRowBuilder<TextInputBuilder>({
components: [
{
custom_id: "username",
max_length: 20,
placeholder: "Display name",
style: TextInputStyle.Short,
label: "Your display name",
type: ComponentType.TextInput
}
]
});

this.modalBuilder = new ModalBuilder().setCustomId("schedule_builder").setTitle("Input your schedule here!").addComponents(firstActionRow.toJSON());
This does not:
const firstActionRow = new ActionRowBuilder<TextInputBuilder>({
components: [
{
custom_id: "username",
max_length: 20,
placeholder: "Display name",
style: TextInputStyle.Short,
label: "Your display name",
type: ComponentType.TextInput
}
]
});

this.modalBuilder = new ModalBuilder().setCustomId("schedule_builder").setTitle("Input your schedule here!").addComponents(firstActionRow);
const firstActionRow = new ActionRowBuilder<TextInputBuilder>({
components: [
{
custom_id: "username",
max_length: 20,
placeholder: "Display name",
style: TextInputStyle.Short,
label: "Your display name",
type: ComponentType.TextInput
}
]
});

this.modalBuilder = new ModalBuilder().setCustomId("schedule_builder").setTitle("Input your schedule here!").addComponents(firstActionRow);
This does not have the same issue, the component can be an object:
const username = new TextInputBuilder()
.setCustomId("username")
.setMaxLength(20)
.setPlaceholder("Display name")
.setLabel("Your display name")
.setRequired(true)
.setStyle(TextInputStyle.Short);

const firstActionRow = new ActionRowBuilder<TextInputBuilder>().addComponents(username);
const username = new TextInputBuilder()
.setCustomId("username")
.setMaxLength(20)
.setPlaceholder("Display name")
.setLabel("Your display name")
.setRequired(true)
.setStyle(TextInputStyle.Short);

const firstActionRow = new ActionRowBuilder<TextInputBuilder>().addComponents(username);
ierdna100
ierdna100OP11mo ago
No description
ierdna100
ierdna100OP11mo ago
Should I setup a new JS project to test it? Youre right, I cant reproduce it at all, even in the same project but clean (ran npm init and all that jazz) Very odd Thanks, I guess
Want results from more Discord servers?
Add your server