{"record":{"id":"4ff3c60be2ac3617","repo":"mobxjs/mobx","slug":"found-non-mobx-decorator-expr-name","errorCode":null,"errorMessage":"Found non-mobx decorator @${expr.name}","messagePattern":"Found non-mobx decorator @(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/mobx-undecorate/src/undecorate.ts","lineNumber":398,"sourceCode":"            membersMap: [[any, any, boolean, boolean]]\n        },\n        clazzPath: ASTPath<ClassDeclaration>\n    ): ClassProperty | ClassMethod {\n        const decorators = property.decorators\n        if (!decorators || decorators.length === 0) {\n            return property\n        }\n        if (decorators.length > 1) {\n            warn(\"Found multiple decorators, skipping..\", property.decorators[0])\n            return property\n        }\n        const decorator = decorators[0]\n        if (!j.Decorator.check(decorator)) {\n            return property\n        }\n        let expr = decorator.expression\n        if (j.Identifier.check(expr) && !decoratorsUsed.has(expr.name)) {\n            warn(`Found non-mobx decorator @${expr.name}`, decorator)\n            return property\n        }\n        if (property.static) {\n            warn(`Static properties are not supported ${property.key.loc?.source}`, property)\n            return property\n        }\n\n        if (options?.keepDecorators !== true) {\n            property.decorators.splice(0)\n        }\n\n        // Replace decorator with @override\n        if ((property as any).override) {\n            const overrideDecorator = j.decorator(j.identifier(\"override\"))\n            if (options?.keepDecorators) {\n                property.decorators[0] = overrideDecorator\n            }\n            expr = overrideDecorator.expression","sourceCodeStart":380,"sourceCodeEnd":416,"githubUrl":"https://github.com/mobxjs/mobx/blob/01211a698b64ea94de8e5f276ff8235fcf8ddf96/packages/mobx-undecorate/src/undecorate.ts#L380-L416","documentation":"The codemod only knows the mobx decorators that were used in `decorate(...)` calls it has seen. A single decorator on a member whose identifier is not in that known set is treated as a non-mobx (custom) decorator and skipped, since rewriting it would change semantics.","triggerScenarios":"A member decorated with an identifier (e.g. `@customlog foo`) that is not among the decorators collected from decorate calls — the identifier is not in `decoratorsUsed`.","commonSituations":"Custom project decorators (logging, formatting), decorators from non-mobx libraries, or mobx decorators used directly on class members without a corresponding `decorate` call so they were never registered in the known set.","solutions":["Register the decorator by adding it to a `decorate(MyClass, { member: yourDecorator })` call if it is actually a mobx-compatible decorator, then re-run the codemod.","Remove or manually rewrite non-mobx decorators, converting their logic to explicit code.","If it is a mobx decorator applied inline (no decorate call), convert the member manually to `makeObservable`."],"exampleFix":"// before\n@log count = 1\n// after\nconstructor() { makeObservable(this, { count: observable }) }\n// plus manual logging code\n","handlingStrategy":"validation","validationCode":"const mobxDecorators = new Set(['observable','computed','action','flow','bound','override','autobind'])\nconst used = [...src.matchAll(/^\\s*@([A-Za-z_$][\\w$]*)/gm)].map(m => m[1])\nconst unknown = used.filter(n => !mobxDecorators.has(n))\nif (unknown.length) console.warn('Non-mobx decorators present:', unknown)","typeGuard":"function isMobxDecorator(name, decoratorsUsed) {\n  return typeof name === 'string' && decoratorsUsed.has(name)\n}","tryCatchPattern":null,"preventionTips":["Register custom decorators via decorate(...) calls if they should be transformed","Convert pure-custom decorators to plain code before migration","Keep an inventory of which decorators in your codebase are mobx vs custom"],"tags":["codemod","decorators","custom-decorator","mobx-undecorate"],"backgroundTag":"codemod-skipped-unsupported-pattern","analyzedSha":"01211a698b64ea94de8e5f276ff8235fcf8ddf96","analyzedAt":"2026-08-28T22:10:08.831Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}