Custom Store not working

Hey guys, I tried myself on writing a custom store
import { Piece, Store } from '@sapphire/framework';

export class InfrastructureDiscordServiceStore extends Store<Piece, 'infrastructure-discord-services'> {
public constructor() {
super(Piece, { name: 'infrastructure-discord-services' });
}
}
import { Piece, Store } from '@sapphire/framework';

export class InfrastructureDiscordServiceStore extends Store<Piece, 'infrastructure-discord-services'> {
public constructor() {
super(Piece, { name: 'infrastructure-discord-services' });
}
}
I try to register it in my client with this code piece
const root = getRootData().root;
this.stores.register(new InfrastructureDiscordServiceStore()).registerPath(join(root, 'infrastructure', 'discord', 'service'));
const root = getRootData().root;
this.stores.register(new InfrastructureDiscordServiceStore()).registerPath(join(root, 'infrastructure', 'discord', 'service'));
Log output:
2025-05-26 10:39:14 - INFO - └─ Loaded 0 infrastructure-discord-services.
2025-05-26 10:39:14 - INFO - └─ Loaded 0 infrastructure-discord-services.
Path should be correct. But at the end no store will be registered. My stores are all built like this
export class RoleService extends Piece {
public constructor(context: Piece.LoaderContext, options: Piece.Options) {
super(context, { ...options, name: 'role-service' });
}
}
export class RoleService extends Piece {
public constructor(context: Piece.LoaderContext, options: Piece.Options) {
super(context, { ...options, name: 'role-service' });
}
}
In the end it's not working. Funny thing is that when I try to register the store manually with
void this.stores.loadPiece({
store: 'infrastructure-discord-services',
name: 'role-service',
piece: RoleService
});
void this.stores.loadPiece({
store: 'infrastructure-discord-services',
name: 'role-service',
piece: RoleService
});
the Service is registered in the store. Log output:
2025-05-26 10:39:14 - INFO - └─ Loaded 6 infrastructure-discord-services.
2025-05-26 10:39:14 - INFO - └─ Loaded 6 infrastructure-discord-services.
What am I doing wrong? I am thankful for all help 🥲
Solution:
specifically plugins dont do this.stores.register(new InfrastructureDiscordServiceStore()) but this.stores.register(this.server.routes) and assign this.server beforehand. They also dont do registerPath which is implied to be join(getRootData().root, nameOfTheStore)
Jump to solution
9 Replies
Favna
Favna5mo ago
have you tried mimicking how stores are registered for plugins?
Solution
Favna
Favna5mo ago
specifically plugins dont do this.stores.register(new InfrastructureDiscordServiceStore()) but this.stores.register(this.server.routes) and assign this.server beforehand. They also dont do registerPath which is implied to be join(getRootData().root, nameOfTheStore)
ShowCast
ShowCastOP5mo ago
Yes I tried to, but I'm not sure how, where and when to mimick the preInitialization hook for example from the util-store plugin from the register.ts. I understand the logic but I'm not sure how am I supposed to do it. Are there any examples on custom stores outside of the plugins?
Favna
Favna5mo ago
how, where and when to mimick the preInitialization hook
in your entrypoint file. index.ts, setup.ts, etc.
ShowCast
ShowCastOP5mo ago
Can I use hooks like as the plugins use? As for some services I need a logged in Bot for example. 2nd question: Can I still do the .registerPath() method somewhere in the files then? My pieces do not live in the path join(getRootData().root, nameOfTheStore) as I'm using some other folder structure
Favna
Favna5mo ago
yes and yes
ShowCast
ShowCastOP5mo ago
Alright. I tried to copy and edit the most of the utilities plugin. This is my store register call
public static [preInitialization](this: SapphireClient): void {
this.discordServices = new DiscordServices();
this.stores.register(this.discordServices.store).registerPath(join(getRootData().root, 'infrastructure', 'discord', 'service'));
}
public static [preInitialization](this: SapphireClient): void {
this.discordServices = new DiscordServices();
this.stores.register(this.discordServices.store).registerPath(join(getRootData().root, 'infrastructure', 'discord', 'service'));
}
import { Store } from '@sapphire/framework';
import { DiscordService } from './DiscordService';
import { join } from 'path';
import { getRootData } from '@sapphire/pieces';

export class InfrastructureDiscordServiceStore extends Store<DiscordService, 'discordServices'> {
public constructor() {
super(DiscordService, { name: 'discordServices', paths: [join(getRootData().root, 'infrastructure', 'discord', 'service')] });
}
}
import { Store } from '@sapphire/framework';
import { DiscordService } from './DiscordService';
import { join } from 'path';
import { getRootData } from '@sapphire/pieces';

export class InfrastructureDiscordServiceStore extends Store<DiscordService, 'discordServices'> {
public constructor() {
super(DiscordService, { name: 'discordServices', paths: [join(getRootData().root, 'infrastructure', 'discord', 'service')] });
}
}
Now there are 2 paths set. First the discord-bot\dist\infrastructure\discord\serviceand discord-bot\dist\discordServices. I tried to set paths in the Store itself. How can I prevent the 2nd store path prevent beeing registered?
Favna
Favna5mo ago
uhm not sure tbh but it doesnt really matter just dont create the direct ory and dont put files in it take for example sapphire Args. If I dont have Args that doesnt mean that the Argument store doesnt have the path registered. It's just sitting there doing nothing.
ShowCast
ShowCastOP5mo ago
Alright, then this will do the trick. It's working by now. Thanks for the help :PES_CowboyLove:

Did you find this page helpful?