BabylonJS/Babylon.js · error
EditableInPropertyPage: decorator metadata is unavailable; t
Error message
EditableInPropertyPage: decorator metadata is unavailable; the Symbol.metadata (${String(MetadataSymbol)}) polyfill must run before decorated classes are evaluated. What it means
The EditableInPropertyPage decorator (Stage decorator API) stores property-editing metadata on context.metadata, which is only populated when Symbol.metadata is installed (native or via the MetadataSymbol polyfill from core). If a decorated class is evaluated before the polyfill runs, context.metadata is undefined and this error is thrown. It is deliberately a hard failure so decorated classes are never silently stripped of editor metadata.
Source
Thrown at packages/dev/smartFilters/src/editorUtils/editableInPropertyPage.ts:107
* @param propertyType - the type of the property
* @param groupName - the group name of the property
* @param options - the options of the property
* @returns the decorator
*/
export function EditableInPropertyPage(
displayName: string,
propertyType: PropertyTypeForEdition = PropertyTypeForEdition.Boolean,
groupName: string = "PROPERTIES",
options?: IEditablePropertyOption
) {
return (_value: unknown, context: { name: string | symbol; metadata: DecoratorMetadataObject }) => {
const meta = context.metadata as DecoratorMetadataObject | undefined;
if (!meta) {
// `context.metadata` is `void 0` when `Symbol.metadata` was not installed before this class
// was evaluated. Importing `MetadataSymbol` from core runs the polyfill at module load (before
// this class body), so this should never happen; referencing it here also keeps that
// module-load polyfill anchored against bundler tree-shaking.
throw new Error(
`EditableInPropertyPage: decorator metadata is unavailable; the Symbol.metadata (${String(MetadataSymbol)}) polyfill must run before decorated classes are evaluated.`
);
}
let propStore: IPropertyDescriptionForEdition[];
if (Object.prototype.hasOwnProperty.call(meta, __bjsSmartFilterPropStoreKey)) {
propStore = meta[__bjsSmartFilterPropStoreKey] as IPropertyDescriptionForEdition[];
} else {
propStore = [];
meta[__bjsSmartFilterPropStoreKey] = propStore;
}
const propertyKey = String(context.name);
const propToAdd: IPropertyDescriptionForEdition = {
propertyName: propertyKey,
displayName: displayName,
type: propertyType,
groupName: groupName,
View on GitHub (pinned to 0592b347b8)
Solutions
- Import MetadataSymbol from core at the very top of your entry point (e.g. import 'core/Misc/decorator.metadata' equivalent) so the polyfill runs before any decorated class loads.
- Keep the polyfill import side-effectful (do not rely on named bindings bundlers may tree-shake).
- Fix import cycles so the polyfill module is not loaded after decorated class modules.
- Use a JS runtime/engine version that supports native Symbol.metadata.
Example fix
// before
import { EditableInPropertyPage } from "@babylonjs/smartFilters/Editor/editableInPropertyPage";
import { MyBlock } from "./myBlock";
// after
import { MetadataSymbol } from "@babylonjs/core/Misc/metadata.symbol"; // polyfill side-effect first
import { EditableInPropertyPage } from "@babylonjs/smartFilters/Editor/editableInPropertyPage";
import { MyBlock } from "./myBlock"; Defensive patterns
Strategy: validation
Validate before calling
if (typeof Symbol.metadata === "undefined") {
// polyfill not installed yet
throw new Error("Import MetadataSymbol from core before importing decorated classes");
} Type guard
null
Try / catch
try {
const mod = await import("./blocks/decoratedBlocks");
} catch (e) {
if (String(e).includes("decorator metadata is unavailable")) {
console.error("Ensure the Symbol.metadata polyfill import precedes decorated class imports");
} else throw e;
} Prevention
- Import the MetadataSymbol polyfill as the first import in your app entry point.
- Mark the polyfill import as side-effectful so bundlers do not tree-shake it.
- Avoid import cycles between decorated class modules and the polyfill module.
- Prefer runtimes with native Symbol.metadata support.
When it happens
Trigger: Importing a module containing @editableInPropertyPage-decorated classes without first importing MetadataSymbol from core; bundler tree-shaking removing the polyfill import; circular imports where the decorated class module loads before the polyfill module.
Common situations: Reordering imports after a refactor; a bundler (Vite/Rollup/webpack) dropping a side-effect-only import it considers unused; migrating Babylon.js versions where the Symbol.metadata polyfill was introduced.
Related errors
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/e1f211962d900635.
Report an issue: GitHub.