BabylonJS/Babylon.js · error
Source block ${connection.outputBlock} not found
Error message
Source block ${connection.outputBlock} not found What it means
When reconstructing connections, the deserializer looks up the connection's output (source) block by name or id in the maps built from the already-deserialized blocks. If no block matches connection.outputBlock, the serialized connection graph is dangling and deserialization fails. This validates referential integrity of the filter's connection list.
Source
Thrown at packages/dev/smartFilters/src/serialization/smartFilterDeserializer.ts:95
serializedSmartFilter.blocks.forEach((serializedBlock: ISerializedBlockV1) => {
blockDeserializationWork.push(
this._deserializeBlockV1Async(smartFilter, serializedBlock, engine, blockDefinitionsWhichCouldNotBeDeserialized, blockIdMap, blockNameMap)
);
});
await Promise.all(blockDeserializationWork);
// If any block definitions could not be deserialized, throw an error
if (blockDefinitionsWhichCouldNotBeDeserialized.length > 0) {
throw new Error(`Could not deserialize the following block definitions: ${blockDefinitionsWhichCouldNotBeDeserialized.join(", ")}`);
}
// Deserialize the connections
serializedSmartFilter.connections.forEach((connection: ISerializedConnectionV1) => {
// Find the source block and its connection point's connectTo function
const sourceBlock = typeof connection.outputBlock === "string" ? blockNameMap.get(connection.outputBlock) : blockIdMap.get(connection.outputBlock);
if (!sourceBlock) {
throw new Error(`Source block ${connection.outputBlock} not found`);
}
const sourceConnectionPoint = sourceBlock.outputs.find((output) => output.name === connection.outputConnectionPoint);
if (!sourceConnectionPoint || typeof sourceConnectionPoint.connectTo !== "function") {
throw new Error(`Block ${connection.outputBlock} does not have an connection point named ${connection.outputConnectionPoint}`);
}
const sourceConnectToFunction = sourceConnectionPoint.connectTo.bind(sourceConnectionPoint);
// Find the target block and its connection point
const targetBlock = typeof connection.inputBlock === "string" ? blockNameMap.get(connection.inputBlock) : blockIdMap.get(connection.inputBlock);
if (!targetBlock) {
throw new Error(`Target block ${connection.inputBlock} not found`);
}
const targetConnectionPoint = targetBlock.inputs.find((input) => input.name === connection.inputConnectionPoint);
if (!targetConnectionPoint || typeof targetConnectionPoint !== "object") {
throw new Error(`Block ${connection.inputBlock} does not have a connection point named ${connection.inputConnectionPoint}`);
}
View on GitHub (pinned to 0592b347b8)
Solutions
- Fix or remove the dangling connection entry in the serialized JSON so outputBlock matches an existing block's name or uniqueId.
- Re-export the filter from the editor instead of hand-editing connection data.
- Validate that every connection's outputBlock exists in serializedSmartFilter.blocks before deserializing.
- Check for name-vs-id mismatch: strings resolve via blockNameMap, numbers via blockIdMap — ensure the field type matches how blocks were serialized.
- If blocks failed to deserialize earlier (864), fix those registrations; the missing blocks cause downstream lookup failures.
Example fix
// before
{ "outputBlock": "BlurOld", "outputConnectionPoint": "out", ... } // no such block
// after
{ "outputBlock": "Blur", "outputConnectionPoint": "out", ... } // matches a deserialized block name Defensive patterns
Strategy: validation
Validate before calling
function validateSourceBlocks(serialized) {
const names = new Set(serialized.blocks.map((b) => b.name));
const ids = new Set(serialized.blocks.map((b) => b.uniqueId));
for (const c of serialized.connections) {
const ok = typeof c.outputBlock === "string" ? names.has(c.outputBlock) : ids.has(c.outputBlock);
if (!ok) throw new Error(`Connection references missing outputBlock: ${c.outputBlock}`);
}
} Type guard
function sourceBlockExists(conn, blocks) {
const map = new Map(blocks.flatMap((b) => [[b.name, b], [b.uniqueId, b]]));
return map.has(conn.outputBlock);
} Try / catch
try {
const filter = await SmartFilterDeserializer.DeserializeAsync(runtime, container, json);
} catch (e) {
if (/Source block .+ not found/.test(e.message)) {
throw new Error("Filter JSON has a connection to a missing source block — repair or re-export the file");
}
throw e;
} Prevention
- Never hand-edit connection lists; re-export from the editor.
- Delete blocks together with their connections.
- Pre-validate all connection endpoints against the blocks array.
- Keep name/id semantics: strings are names, numbers are uniqueIds.
- Back up working filter files before manual edits.
When it happens
Trigger: A serialized connection references an outputBlock whose block failed to deserialize (removed after error 864 collection is bypassed — no, blocks that failed cause 864; here the block is simply absent from JSON), the name/id was renamed in the JSON, or connection entries were hand-edited or merged incorrectly.
Common situations: Hand-editing .smartfilter JSON, deleting a block in the editor while stale connections remain, older exports using ids that no longer match, concatenating filters incorrectly.
Related errors
- `Target block ${connection.inputBlock} not found`
- Block ${connection.outputBlock} does not have an connection
- `Block ${connection.inputBlock} does not have a connection p
- SmartAssetSerializer: Invalid asset map — 'assets' must be a
- SmartAssetSerializer: Invalid entry for key "${key}" — expec
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/f310a3295b1ea055.
Report an issue: GitHub.