From 7f4b96897bd6ea32999507739ff2a4abf2f703ae Mon Sep 17 00:00:00 2001
From: Gorbachev Egor <7gorbachevm@gmail.com>
Date: Wed, 24 Jun 2026 13:44:08 +0700
Subject: [PATCH 1/4] Shorten minified error URL
---
.changeset/fix-minified-error-link.md | 5 ++
.gitignore | 1 +
packages/mobx/src/errors.ts | 2 +-
website/i18n/en.json | 4 ++
website/package.json | 2 +
website/scripts/generate-error-docs.mjs | 69 +++++++++++++++++++++++++
website/sidebars.json | 1 +
7 files changed, 83 insertions(+), 1 deletion(-)
create mode 100644 .changeset/fix-minified-error-link.md
create mode 100644 website/scripts/generate-error-docs.mjs
diff --git a/.changeset/fix-minified-error-link.md b/.changeset/fix-minified-error-link.md
new file mode 100644
index 0000000000..ac68f01ee4
--- /dev/null
+++ b/.changeset/fix-minified-error-link.md
@@ -0,0 +1,5 @@
+---
+"mobx": patch
+---
+
+Shorten minified error URL to reduce production bundle size.
diff --git a/.gitignore b/.gitignore
index 4170db41f5..4059224142 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@ coverage
test/babel-tests.js
test/typescript/typescript-tests.js
dist/
+/docs/errors.md
**/.idea/*
!/.idea/icon.png
!/.idea/vcs.xml
diff --git a/packages/mobx/src/errors.ts b/packages/mobx/src/errors.ts
index 9a97bdc55c..5c72f2fe93 100644
--- a/packages/mobx/src/errors.ts
+++ b/packages/mobx/src/errors.ts
@@ -87,7 +87,7 @@ export function die(error: string | keyof typeof errors, ...args: any[]): never
typeof error === "number"
? `[MobX] minified error nr: ${error}${
args.length ? " " + args.map(String).join(",") : ""
- }. Find the full error at: https://github.com/mobxjs/mobx/blob/main/packages/mobx/src/errors.ts`
+ }. See http://mobx.js.org/errors`
: `[MobX] ${error}`
)
}
diff --git a/website/i18n/en.json b/website/i18n/en.json
index a387a8141d..85973a3fda 100644
--- a/website/i18n/en.json
+++ b/website/i18n/en.json
@@ -64,6 +64,10 @@
"title": "Decorators",
"sidebar_label": "Decorators {🚀}"
},
+ "errors": {
+ "title": "MobX error codes",
+ "sidebar_label": "Error codes"
+ },
"faq/migrate-to-6": {
"title": "Migrating from MobX 4/5"
},
diff --git a/website/package.json b/website/package.json
index 9e0ffd0f0c..31a1b50685 100644
--- a/website/package.json
+++ b/website/package.json
@@ -1,7 +1,9 @@
{
"scripts": {
"examples": "docusaurus-examples",
+ "prestart": "node scripts/generate-error-docs.mjs",
"start": "docusaurus-start",
+ "prebuild": "node scripts/generate-error-docs.mjs",
"build": "docusaurus-build",
"publish-gh-pages": "docusaurus-publish",
"write-translations": "docusaurus-write-translations",
diff --git a/website/scripts/generate-error-docs.mjs b/website/scripts/generate-error-docs.mjs
new file mode 100644
index 0000000000..4b34d58491
--- /dev/null
+++ b/website/scripts/generate-error-docs.mjs
@@ -0,0 +1,69 @@
+#!/usr/bin/env node
+
+import { readFileSync, writeFileSync } from "node:fs"
+import { relative } from "node:path"
+import { fileURLToPath } from "node:url"
+
+const repoRoot = fileURLToPath(new URL("../..", import.meta.url))
+const errorsPath = fileURLToPath(new URL("../../packages/mobx/src/errors.ts", import.meta.url))
+const outputPath = fileURLToPath(new URL("../../docs/errors.md", import.meta.url))
+
+function readNiceErrors() {
+ const source = readFileSync(errorsPath, "utf8")
+ const match = source.match(/const niceErrors = ([\s\S]*?) as const/)
+
+ if (!match) {
+ throw new Error(`Could not find niceErrors in ${errorsPath}`)
+ }
+
+ const objectLiteral = match[1].replace(": PropertyKey", "")
+ return eval(`(${objectLiteral})`)
+}
+
+function getParamNames(fn) {
+ const match = fn.toString().match(/^[^(]*\(([^)]*)\)/)
+ return match ? match[1].split(",").map(name => name.trim()).filter(Boolean) : []
+}
+
+function renderMessage(message) {
+ if (typeof message !== "function") {
+ return message
+ }
+
+ const args = getParamNames(message).map(name => `{${name}}`)
+ return message(...args).replace("String", args[0])
+}
+
+function escapeMarkdownTableCell(value) {
+ return String(value).replace(/\r?\n/g, "
").replace(/\|/g, "\\|")
+}
+
+function renderDocs(errors) {
+ const rows = Object.keys(errors)
+ .sort((left, right) => Number(left) - Number(right))
+ .map(code => `| ${code} | ${escapeMarkdownTableCell(renderMessage(errors[code]))} |`)
+ .join("\n")
+
+ return `---
+title: MobX error codes
+sidebar_label: Error codes
+hide_title: true
+custom_edit_url: https://github.com/mobxjs/mobx/edit/main/packages/mobx/src/errors.ts
+---
+
+
+
+# MobX error codes
+
+In development builds, MobX throws full error messages. Production builds replace known messages with short numeric codes to keep the published bundle small.
+
+| Code | Message |
+| ---- | ------- |
+${rows}
+`
+}
+
+const docs = renderDocs(readNiceErrors())
+writeFileSync(outputPath, docs)
+
+console.log(`Generated ${relative(repoRoot, outputPath)} from ${relative(repoRoot, errorsPath)}`)
diff --git a/website/sidebars.json b/website/sidebars.json
index 107e059688..2d5d8196e8 100755
--- a/website/sidebars.json
+++ b/website/sidebars.json
@@ -22,6 +22,7 @@
"understanding-reactivity",
"subclassing",
"analyzing-reactivity",
+ "errors",
"computeds-with-args",
"mobx-utils",
"custom-observables",
From 117a760b7db352311caa661a68a88f36ffd356ce Mon Sep 17 00:00:00 2001
From: Gorbachev Egor <7gorbachevm@gmail.com>
Date: Wed, 24 Jun 2026 14:34:29 +0700
Subject: [PATCH 2/4] simpler check
---
packages/mobx/src/errors.ts | 2 +-
packages/mobx/src/internal.ts | 2 +-
website/package.json | 4 +--
...-error-docs.mjs => generate-error-docs.js} | 26 ++++++-------------
4 files changed, 12 insertions(+), 22 deletions(-)
rename website/scripts/{generate-error-docs.mjs => generate-error-docs.js} (65%)
diff --git a/packages/mobx/src/errors.ts b/packages/mobx/src/errors.ts
index 5c72f2fe93..9ec23a018c 100644
--- a/packages/mobx/src/errors.ts
+++ b/packages/mobx/src/errors.ts
@@ -1,4 +1,4 @@
-const niceErrors = {
+export const niceErrors = {
0: `Invalid value for configuration 'enforceActions', expected 'never', 'always' or 'observed'`,
1(annotationType, key: PropertyKey) {
return `Cannot apply '${annotationType}' to '${key.toString()}': Field not found.`
diff --git a/packages/mobx/src/internal.ts b/packages/mobx/src/internal.ts
index 1317b234c3..48885069a4 100644
--- a/packages/mobx/src/internal.ts
+++ b/packages/mobx/src/internal.ts
@@ -6,7 +6,7 @@ With this file that will still happen,
but at least in this file we can magically reorder the imports with trial and error until the build succeeds again.
*/
export * from "./utils/global"
-export * from "./errors"
+export { die } from "./errors"
export * from "./utils/utils"
export * from "./api/decorators"
export * from "./core/atom"
diff --git a/website/package.json b/website/package.json
index 31a1b50685..3aaa2577f5 100644
--- a/website/package.json
+++ b/website/package.json
@@ -1,9 +1,9 @@
{
"scripts": {
"examples": "docusaurus-examples",
- "prestart": "node scripts/generate-error-docs.mjs",
+ "prestart": "node scripts/generate-error-docs.js",
"start": "docusaurus-start",
- "prebuild": "node scripts/generate-error-docs.mjs",
+ "prebuild": "node scripts/generate-error-docs.js",
"build": "docusaurus-build",
"publish-gh-pages": "docusaurus-publish",
"write-translations": "docusaurus-write-translations",
diff --git a/website/scripts/generate-error-docs.mjs b/website/scripts/generate-error-docs.js
similarity index 65%
rename from website/scripts/generate-error-docs.mjs
rename to website/scripts/generate-error-docs.js
index 4b34d58491..8e74076564 100644
--- a/website/scripts/generate-error-docs.mjs
+++ b/website/scripts/generate-error-docs.js
@@ -1,24 +1,14 @@
#!/usr/bin/env node
-import { readFileSync, writeFileSync } from "node:fs"
-import { relative } from "node:path"
-import { fileURLToPath } from "node:url"
+const { writeFileSync } = require("fs")
+const { relative, resolve } = require("path")
-const repoRoot = fileURLToPath(new URL("../..", import.meta.url))
-const errorsPath = fileURLToPath(new URL("../../packages/mobx/src/errors.ts", import.meta.url))
-const outputPath = fileURLToPath(new URL("../../docs/errors.md", import.meta.url))
+const repoRoot = resolve(__dirname, "../..")
+const errorsPath = resolve(repoRoot, "packages/mobx/src/errors.ts")
+const outputPath = resolve(repoRoot, "docs/errors.md")
-function readNiceErrors() {
- const source = readFileSync(errorsPath, "utf8")
- const match = source.match(/const niceErrors = ([\s\S]*?) as const/)
-
- if (!match) {
- throw new Error(`Could not find niceErrors in ${errorsPath}`)
- }
-
- const objectLiteral = match[1].replace(": PropertyKey", "")
- return eval(`(${objectLiteral})`)
-}
+globalThis.__DEV__ = true
+const { niceErrors } = require(errorsPath)
function getParamNames(fn) {
const match = fn.toString().match(/^[^(]*\(([^)]*)\)/)
@@ -63,7 +53,7 @@ ${rows}
`
}
-const docs = renderDocs(readNiceErrors())
+const docs = renderDocs(niceErrors)
writeFileSync(outputPath, docs)
console.log(`Generated ${relative(repoRoot, outputPath)} from ${relative(repoRoot, errorsPath)}`)
From 620da5bf7d071a5d6d5020a64aaaecbd94b9be28 Mon Sep 17 00:00:00 2001
From: Gorbachev Egor <7gorbachevm@gmail.com>
Date: Wed, 24 Jun 2026 14:39:25 +0700
Subject: [PATCH 3/4] simpler code
---
website/scripts/generate-error-docs.js | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/website/scripts/generate-error-docs.js b/website/scripts/generate-error-docs.js
index 8e74076564..141ab3e28c 100644
--- a/website/scripts/generate-error-docs.js
+++ b/website/scripts/generate-error-docs.js
@@ -10,28 +10,26 @@ const outputPath = resolve(repoRoot, "docs/errors.md")
globalThis.__DEV__ = true
const { niceErrors } = require(errorsPath)
-function getParamNames(fn) {
- const match = fn.toString().match(/^[^(]*\(([^)]*)\)/)
- return match ? match[1].split(",").map(name => name.trim()).filter(Boolean) : []
-}
-
-function renderMessage(message) {
- if (typeof message !== "function") {
- return message
+function formatMarkdownCell(message) {
+ let value = message
+
+ if (typeof message === "function") {
+ // Render dynamic errors with visible placeholders instead of real runtime values
+ const match = message.toString().match(/^[^(]*\(([^)]*)\)/)
+ const params = match ? match[1] : ""
+ const names = params.split(",").map(name => name.trim()).filter(Boolean)
+ const args = names.map(name => `{${name}}`)
+ value = message(...args).replace("String", args[0])
}
- const args = getParamNames(message).map(name => `{${name}}`)
- return message(...args).replace("String", args[0])
-}
-
-function escapeMarkdownTableCell(value) {
+ // Keep the generated table valid Markdown
return String(value).replace(/\r?\n/g, "
").replace(/\|/g, "\\|")
}
function renderDocs(errors) {
const rows = Object.keys(errors)
.sort((left, right) => Number(left) - Number(right))
- .map(code => `| ${code} | ${escapeMarkdownTableCell(renderMessage(errors[code]))} |`)
+ .map(code => `| ${code} | ${formatMarkdownCell(errors[code])} |`)
.join("\n")
return `---
From ed467aa500bf651351819abcc73156169bdb4458 Mon Sep 17 00:00:00 2001
From: Gorbachev Egor <7gorbachevm@gmail.com>
Date: Wed, 24 Jun 2026 14:48:14 +0700
Subject: [PATCH 4/4] wording
---
website/scripts/generate-error-docs.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/website/scripts/generate-error-docs.js b/website/scripts/generate-error-docs.js
index 141ab3e28c..aa9db32ec5 100644
--- a/website/scripts/generate-error-docs.js
+++ b/website/scripts/generate-error-docs.js
@@ -43,7 +43,7 @@ custom_edit_url: https://github.com/mobxjs/mobx/edit/main/packages/mobx/src/erro
# MobX error codes
-In development builds, MobX throws full error messages. Production builds replace known messages with short numeric codes to keep the published bundle small.
+In development builds, MobX throws full error messages. Production builds replace known messages with short numeric codes to keep the published bundle smaller.
| Code | Message |
| ---- | ------- |