medusajs/medusa · error · MedusaError
Trying to register a fulfillment provider without an identif
Error message
Trying to register a fulfillment provider without an identifier.
What it means
Static validator used when registering fulfillment provider plugin classes. A provider class must declare a static `identifier` property; without it the registration key (`identifier_optionName`) cannot be built and an INVALID_ARGUMENT error is thrown.
Source
Thrown at packages/modules/fulfillment/src/services/fulfillment-provider.ts:51
) {
protected readonly fulfillmentProviderRepository_: DAL.RepositoryService
#logger: Logger
constructor(container: InjectedDependencies) {
super(container)
this.fulfillmentProviderRepository_ =
container.fulfillmentProviderRepository
this.#logger = container["logger"]
? container.logger
: (console as unknown as Logger)
}
static getRegistrationIdentifier(
providerClass: Constructor<IFulfillmentProvider>,
optionName?: string
) {
if (!(providerClass as any).identifier) {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
`Trying to register a fulfillment provider without an identifier.`
)
}
return `${(providerClass as any).identifier}_${optionName}`
}
protected retrieveProviderRegistration(
providerId: string
): FulfillmentTypes.IFulfillmentProvider {
try {
return this.__container__[`fp_${providerId}`]
} catch (err) {
if (err.name === "AwilixResolutionError") {
const errMessage = `
Unable to retrieve the fulfillment provider with id: ${providerId}
Please make sure that the provider is registered in the container and it is configured correctly in your project configuration file.`
View on GitHub (pinned to 5e06e544a2)
Solutions
- Add `static identifier = "..."` to the provider class
- If it also has options, also set `static identifier` plus option registration via provider loader conventions
- Ensure you export the class itself, not an instance
Example fix
// before
class MyFulfillmentProvider extends AbstractFulfillmentService { ... }
// after
class MyFulfillmentProvider extends AbstractFulfillmentService {
static identifier = 'my-fulfillment'
// ...
} Defensive patterns
Strategy: validation
Validate before calling
import { FulfillmentProvider } from '@medusajs/fulfillment'
// before registration
if (!(MyProvider as any).identifier) throw new Error('Provider missing static identifier') Type guard
const hasIdentifier = (cls: any): boolean => typeof cls?.identifier === 'string' && cls.identifier.length > 0
Prevention
- Always declare `static identifier` on custom providers
- Write a unit test asserting the static exists for each provider
When it happens
Trigger: Registering a custom fulfillment provider class that lacks `static identifier = 'my-provider'`, or where identifier is set only on instances/prototype instead of the class.
Common situations: Writing a first custom provider and forgetting the static field; refactoring a provider from an object to a class and losing the static.
Related errors
- Unable to retrieve the fulfillment provider with id: ${provi
- Unable to retrieve the fulfillment provider with id: ${provi
- Module ${moduleConfig.resolve} doesn't have a serviceName. P
- Unable to resolve plugin "${pluginPath}". Make sure the plug
- The specified PostgreSQL database does not exist. Please cre
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/1ce39bce3f26703a.
Report an issue: GitHub.