BabylonJS/Babylon.js · error · Error

`No serializer was provided for a block of type ${block.bloc

Error message

`No serializer was provided for a block of type ${block.blockType}`

What it means

During serialization every block must be mapped to a serializer function. Shader-like custom blocks (InputOutputBlock-derived / CustomShaderBlock) fall back to built-in serializers, but all other custom block types must have been registered in the SmartFilterSerializer's _blockSerializers map. If a block's blockType has no registered serializer, serialization aborts because the block could not be represented in the output JSON.

Source

Thrown at packages/dev/smartFilters/src/serialization/smartFilterSerializer.ts:70

    /**
     * Serializes a SmartFilter to a JSON object of the latest version
     * @param smartFilter - The SmartFilter to serialize
     * @returns The serialized SmartFilter
     */
    public serialize(smartFilter: SmartFilter): SerializedSmartFilterV1 {
        const connections: ISerializedConnectionV1[] = [];

        const blocks = smartFilter.attachedBlocks.map((block: BaseBlock) => {
            // Serialize the block itself
            const blockClassName = block.getClassName();
            const serializeFn =
                blockClassName === CustomShaderBlock.ClassName
                    ? CustomShaderBlockSerializer
                    : blockClassName === CustomAggregateBlock.ClassName
                      ? DefaultBlockSerializer
                      : this._blockSerializers.get(block.blockType);
            if (!serializeFn) {
                throw new Error(`No serializer was provided for a block of type ${block.blockType}`);
            }
            const serializedBlock: ISerializedBlockV1 = serializeFn(block);

            // Serialize the connections to the inputs
            block.inputs.forEach((input: ConnectionPoint) => {
                const connectedTo = input.connectedTo;
                if (connectedTo) {
                    const newConnection: ISerializedConnectionV1 = {
                        inputBlock: block.uniqueId,
                        inputConnectionPoint: input.name,
                        outputBlock: connectedTo.ownerBlock.uniqueId,
                        outputConnectionPoint: connectedTo.name,
                    };
                    if (!connections.find((other) => SerializedConnectionPointsEqual(newConnection, other))) {
                        connections.push(newConnection);
                    }
                }
            });

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Register a serializer for the block type before serializing: serializer.registerSerializer(blockType, CustomBlockSerializer).
  2. Import the module side-effects that register all custom block serializers used by the filter.
  3. Verify block.blockType on the failing block matches the key used at registration (log block.blockType to compare).
  4. Use a DefaultBlockSerializer fallback for simple blocks if a dedicated serializer is unnecessary.
  5. Re-create the serializer instance if registrations were made on a different instance than the one used for serialize().

Example fix

// before
const serializer = new SmartFilterSerializer(smartFilter);
const json = serializer.serialize(); // custom type missing
// after
const serializer = new SmartFilterSerializer(smartFilter);
serializer.registerSerializer("MyCustomBlock", MyCustomBlockSerializer);
const json = serializer.serialize();
Defensive patterns

Strategy: try-catch

Validate before calling

function assertAllBlocksSerializable(smartFilter, serializer) {
  for (const block of smartFilter.attachedBlocks) {
    const known = ["InputBlock", "OutputBlock", "CustomShaderBlock", "CustomAggregateBlock"]
      .some((c) => block.getClassName() === c) || serializer.hasSerializer(block.blockType);
    if (!known) throw new Error(`No serializer registered for ${block.blockType}`);
  }
}

Type guard

function hasSerializerFor(serializer, block) {
  return typeof serializer._blockSerializers?.get(block.blockType) === "function";
}

Try / catch

try {
  const json = serializer.serialize();
} catch (e) {
  const m = e.message.match(/No serializer was provided for a block of type (.+)/);
  if (m) {
    serializer.registerSerializer(m[1], DefaultBlockSerializer);
    return serializer.serialize();
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling smartFilterSerializer.serialize() on a filter containing a custom block whose type was never registered with serializer.registerSerializer(blockType, fn), or a blockType renamed so the registration key no longer matches.

Common situations: Serializing filters with third-party/custom blocks in a runtime that skipped the registration step, registering under one blockType string while the block instance reports another (name drift after refactors), serializing before custom block modules were imported.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/83d3a936c6d637e2. Report an issue: GitHub.