{"record":{"id":"779fa1576f62faaf","repo":"mobxjs/mobx","slug":"expected-a-decorate-call-with-two-arguments","errorCode":null,"errorMessage":"Expected a decorate call with two arguments","messagePattern":"Expected a decorate call with two arguments","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/mobx-undecorate/src/undecorate.ts","lineNumber":165,"sourceCode":"            if (decorateIndex !== -1) {\n                im.value.specifiers?.splice(decorateIndex, 1)\n            }\n        }\n    })\n\n    // rewrite all decorate calls to class decorators\n    if (usesDecorate) {\n        source\n            .find(j.CallExpression)\n            .filter(\n                callPath =>\n                    j.Identifier.check(callPath.value.callee) &&\n                    callPath.value.callee.name === \"decorate\"\n            )\n            .forEach(callPath => {\n                let canRemoveDecorateCall = true\n                if (callPath.value.arguments.length !== 2) {\n                    warn(\"Expected a decorate call with two arguments\", callPath.value)\n                    return\n                }\n                const target = callPath.value.arguments[0]\n                const decorators = callPath.value.arguments[1]\n\n                if (!j.Identifier.check(target)) {\n                    // not targeting a class, just swap it with makeObservable\n                    changed = true\n                    // @ts-ignore // TODO: or \"observable\" ?\n                    callPath.value.callee.name = \"makeObservable\"\n                    needsInitializeImport = true\n                    return\n                }\n                const declarations = callPath.scope.getBindings()[target.name]\n                if (declarations.length === 0) {\n                    warn(\n                        `Expected exactly one class declaration for '${target.name}' but found ${declarations.length}`,\n                        target","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/mobxjs/mobx/blob/01211a698b64ea94de8e5f276ff8235fcf8ddf96/packages/mobx-undecorate/src/undecorate.ts#L147-L183","documentation":"The mobx-undecorate codemod rewrites legacy `decorate(klass, decorators)` calls into `makeObservable` calls. The decorate call must take exactly two arguments: the class (or object) and the decorators map. If it finds a `decorate(...)` call with any other argument count, it warns and skips that call, leaving it untransformed.","triggerScenarios":"Running the codemod on a file containing `decorate(X, {...}, extraArg)` or `decorate(X)` — i.e. a decorate invocation whose `arguments.length !== 2`.","commonSituations":"Hand-written helper wrappers around decorate, commented-out or partially edited decorate calls, or code that spread extra arguments into decorate (e.g. debugging leftovers).","solutions":["Edit the file so every `decorate` call has exactly two arguments: the class identifier and a decorators object literal.","If the call is a wrapper or dynamically-built (e.g. `decorate.apply`), rewrite it manually to `makeObservable` and exclude it from the codemod.","Remove dead/obsolete decorate calls before running the codemod."],"exampleFix":"// before\ndecorate(Store, { count: observable }, someExtra)\n// after\ndecorate(Store, { count: observable })","handlingStrategy":"validation","validationCode":"import fs from 'fs'\nconst src = fs.readFileSync(file, 'utf8')\nconst bad = [...src.matchAll(/decorate\\s*\\(([^;]*?)\\)/g)]\n  .filter(m => (m[1].match(/,/g) || []).length !== 1)\nif (bad.length) throw new Error(`decorate calls without exactly 2 args in ${file}`)","typeGuard":"function hasTwoArgs(node) {\n  return Array.isArray(node.arguments) && node.arguments.length === 2\n}","tryCatchPattern":null,"preventionTips":["Ensure every decorate call passes exactly a class/object and a decorators object literal","Remove wrapper functions around decorate before codemodding","Grep for `decorate(` and inspect argument counts before running the codemod"],"tags":["codemod","ast","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"}