mobxjs/mobx · warning
Static properties are not supported ${property.key.loc?.sour
Error message
Static properties are not supported ${property.key.loc?.source} What it means
Static class members decorated with mobx decorators cannot be converted to `makeObservable`, because makeObservable annotations only apply to instances in the constructor. The codemod warns and leaves the static decorated member untouched.
Source
Thrown at packages/mobx-undecorate/src/undecorate.ts:402
const decorators = property.decorators
if (!decorators || decorators.length === 0) {
return property
}
if (decorators.length > 1) {
warn("Found multiple decorators, skipping..", property.decorators[0])
return property
}
const decorator = decorators[0]
if (!j.Decorator.check(decorator)) {
return property
}
let expr = decorator.expression
if (j.Identifier.check(expr) && !decoratorsUsed.has(expr.name)) {
warn(`Found non-mobx decorator @${expr.name}`, decorator)
return property
}
if (property.static) {
warn(`Static properties are not supported ${property.key.loc?.source}`, property)
return property
}
if (options?.keepDecorators !== true) {
property.decorators.splice(0)
}
// Replace decorator with @override
if ((property as any).override) {
const overrideDecorator = j.decorator(j.identifier("override"))
if (options?.keepDecorators) {
property.decorators[0] = overrideDecorator
}
expr = overrideDecorator.expression
}
effects.membersMap.push([
property.key,View on GitHub (pinned to 01211a698b)
Solutions
- Move the static state to a module-level variable annotated with `observable()` from mobx instead of a static class field.
- Remove the decorator and manage the static value with explicit mobx APIs (e.g. `observable.box`).
- Keep the decorator and exclude this file from the codemod if static decorators are essential (not supported on modern decorators anyway).
Example fix
// before
class Store { @observable static count = 0 }
// after
const storeCount = observable.box(0)
class Store { static get count() { return storeCount.get() } } Defensive patterns
Strategy: validation
Validate before calling
if (/static\s+@\w+|@\w+\s+(?:public\s+)?static\s+\w+/.test(src)) {
throw new Error('Decorated static members found; mobx-undecorate cannot convert them')
} Type guard
function isDecoratedStatic(member) {
return member.static && member.decorators && member.decorators.length > 0
} Prevention
- Avoid decorating static class members; use module-level observables instead
- Refactor static observable state to a store instance or observable.box
- Review codemod warnings about static properties after migration
When it happens
Trigger: `handleProperty` finds a decorated member with `property.static === true`, e.g. `static @observable count = 0` (or `@observable static count = 0`).
Common situations: Classes using static observable state (global counters, registries) that were converted from legacy decorate-based code where statics happened to work.
Related errors
- Found multiple decorators, skipping..
- Found non-mobx decorator @${expr.name}
- Unexpected type
- Expected a decorate call with two arguments
- Expected exactly one class declaration for '${target.name}'
AI-assisted analysis of mobxjs/mobx@01211a698b (2026-08-28).
Data as JSON: /api/errors/91c03cba132cbf7c.
Report an issue: GitHub.