mobxjs/mobx · error
Please use `@observable accessor ${String(context.name)}` in
Error message
Please use `@observable accessor ${String(context.name)}` instead of `@observable ${String(context.name)}` What it means
In MobX 6.13+ with standard (non-legacy) decorators, @observable on a class field (decorator context kind === 'field') is no longer supported because native fields cannot be redefined; decorateObservable20223_ throws via die() directing you to the 'accessor' keyword. This applies to the 2022-3 (Stage 3) decorator transform only.
Source
Thrown at packages/mobx/src/types/observableannotation.ts:54
proxyTrap: boolean
): boolean | null {
assertObservableDescriptor(adm, this, key, descriptor)
return adm.defineObservableProperty_(
key,
descriptor.value,
this.options_?.enhancer_ ?? deepEnhancer,
proxyTrap
)
}
export function decorateObservable20223_(
annotation: Annotation,
desc,
context: ClassAccessorDecoratorContext | ClassFieldDecoratorContext
) {
if (__DEV__) {
if (context.kind === "field") {
throw die(
`Please use \`@observable accessor ${String(
context.name
)}\` instead of \`@observable ${String(context.name)}\``
)
}
assert20223DecoratorType(context, ["accessor"])
}
const ann = annotation
const { kind, name } = context
if (kind !== "accessor") {
return
}
// Defer ObservableValue construction until first access. The factory is
// materialised by ObservableObjectAdministration on demand, so unused
// fields on wide classes never pay the per-instance allocation cost.View on GitHub (pinned to 01211a698b)
Solutions
- Change the field to `@observable accessor someField = value` (requires @babel/plugin-proposal-decorators or TS supporting accessor).
- Enable legacy decorators in tsconfig: { "experimentalDecorators": true, "useDefineForClassFields": false }.
- Switch to makeObservable/makeAutoObservable without decorators.
- Pin MobX < 6.13 temporarily if a full migration isn't possible (short-term only).
Example fix
// before (Stage-3 decorators)
class Store {
@observable count = 0
}
// after
class Store {
@observable accessor count = 0
} Defensive patterns
Strategy: validation
Validate before calling
// tsconfig.json check before using @observable on fields with modern decorators:
// { "compilerOptions": { "experimentalDecorators": true, "useDefineForClassFields": false } }
// or, with Stage-3 decorators, require the accessor keyword:
function assertAccessorDecorator(context) {
if (context.kind === 'field') {
throw new Error(`@observable requires 'accessor': use @observable accessor ${String(context.name)}`)
}
return context
} Type guard
function isAccessorContext(ctx) {
return ctx.kind === 'accessor'
} Try / catch
try {
defineStoreClass()
} catch (e) {
if (String(e.message).includes('@observable accessor')) {
throw new Error('Migrate @observable fields to @observable accessor (Stage-3 decorators), or enable experimentalDecorators')
}
throw e
} Prevention
- Use `@observable accessor` in all Stage-3 decorator codebases (MobX >= 6.13).
- Keep experimentalDecorators: true + useDefineForClassFields: false if using legacy decorators.
- Prefer makeAutoObservable in constructor to avoid decorator-mode pitfalls entirely.
- Run the class-definition module in CI tests so decorator throws surface at build/test time.
When it happens
Trigger: Using native/Stage-3 decorators (TypeScript ~5 with 'experimentalDecorators' omitted/false, or Babel's 2023-11 decorator plugin) and declaring `@observable someField = value` on a class — MobX throws immediately at class definition time.
Common situations: Upgrading MobX to 6.13+ in a project using modern decorators without the legacy flag; new TypeScript 5 projects forgetting experimentalDecorators; copying legacy MobX decorator examples into a Stage-3 decorator codebase.
Related errors
- Unexpected type
- mobx-react-lite requires mobx at least version 7 to be avail
- mobx-react requires mobx to be available
- [mobx-react] Cannot read "${admin.name}.${key}" in a reactiv
- [MobX] ${e}
AI-assisted analysis of mobxjs/mobx@01211a698b (2026-08-28).
Data as JSON: /api/errors/0478ad677d334525.
Report an issue: GitHub.