{"record":{"id":"8f9b2544d2339453","repo":"BabylonJS/Babylon.js","slug":"target-block-connection-inputblock-not-found","errorCode":null,"errorMessage":"`Target block ${connection.inputBlock} not found`","messagePattern":"`Target block (.+?) not found`","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/smartFilters/src/serialization/smartFilterDeserializer.ts","lineNumber":106,"sourceCode":"\r\n        // Deserialize the connections\r\n        serializedSmartFilter.connections.forEach((connection: ISerializedConnectionV1) => {\r\n            // Find the source block and its connection point's connectTo function\r\n            const sourceBlock = typeof connection.outputBlock === \"string\" ? blockNameMap.get(connection.outputBlock) : blockIdMap.get(connection.outputBlock);\r\n\r\n            if (!sourceBlock) {\r\n                throw new Error(`Source block ${connection.outputBlock} not found`);\r\n            }\r\n            const sourceConnectionPoint = sourceBlock.outputs.find((output) => output.name === connection.outputConnectionPoint);\r\n            if (!sourceConnectionPoint || typeof sourceConnectionPoint.connectTo !== \"function\") {\r\n                throw new Error(`Block ${connection.outputBlock} does not have an connection point named ${connection.outputConnectionPoint}`);\r\n            }\r\n            const sourceConnectToFunction = sourceConnectionPoint.connectTo.bind(sourceConnectionPoint);\r\n\r\n            // Find the target block and its connection point\r\n            const targetBlock = typeof connection.inputBlock === \"string\" ? blockNameMap.get(connection.inputBlock) : blockIdMap.get(connection.inputBlock);\r\n            if (!targetBlock) {\r\n                throw new Error(`Target block ${connection.inputBlock} not found`);\r\n            }\r\n\r\n            const targetConnectionPoint = targetBlock.inputs.find((input) => input.name === connection.inputConnectionPoint);\r\n            if (!targetConnectionPoint || typeof targetConnectionPoint !== \"object\") {\r\n                throw new Error(`Block ${connection.inputBlock} does not have a connection point named ${connection.inputConnectionPoint}`);\r\n            }\r\n\r\n            // Create the connection\r\n            sourceConnectToFunction.call(sourceBlock, targetConnectionPoint);\r\n        });\r\n\r\n        return smartFilter;\r\n    }\r\n\r\n    private async _deserializeBlockV1Async(\r\n        smartFilter: SmartFilter,\r\n        serializedBlock: ISerializedBlockV1,\r\n        engine: ThinEngine,\r","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/smartFilters/src/serialization/smartFilterDeserializer.ts#L88-L124","documentation":"Symmetric to the source-side lookup: the connection's input (target) block is resolved by name or id, and if no block matches connection.inputBlock the connection cannot be wired and deserialization throws. It indicates a dangling reference in the serialized graph's target side.","triggerScenarios":"A serialized connection references an inputBlock that was never deserialized — block removed from the blocks array, name/id renamed in hand-edited JSON, or ids from a different filter pasted in.","commonSituations":"Hand-editing or programmatically merging .smartfilter files, deleting blocks in the editor while connections remained, version migrations that changed block naming schemes.","solutions":["Fix connection.inputBlock to match an existing deserialized block's name (string) or uniqueId (number).","Remove orphaned connection entries pointing at deleted blocks.","Re-export from the editor rather than editing JSON by hand.","Pre-validate that every connection's inputBlock exists in the blocks array before deserializing.","If blocks failed earlier (error 864), register them — their absence cascades into these lookup errors."],"exampleFix":"// before\n{ \"inputBlock\": 42, \"inputConnectionPoint\": \"a\", ... } // id 42 not in blocks\n// after\n{ \"inputBlock\": 37, \"inputConnectionPoint\": \"a\", ... } // matches a deserialized block id","handlingStrategy":"validation","validationCode":"function validateTargetBlocks(serialized) {\n  const map = new Map(serialized.blocks.flatMap((b) => [[b.name, b], [b.uniqueId, b]]));\n  for (const c of serialized.connections) {\n    if (!map.has(c.inputBlock)) throw new Error(`Connection references missing inputBlock: ${c.inputBlock}`);\n  }\n}","typeGuard":"function targetBlockExists(conn, blocks) {\n  const map = new Map(blocks.flatMap((b) => [[b.name, b], [b.uniqueId, b]]));\n  return map.has(conn.inputBlock);\n}","tryCatchPattern":"try {\n  const filter = await SmartFilterDeserializer.DeserializeAsync(runtime, container, json);\n} catch (e) {\n  if (/Target block .+ not found/.test(e.message)) {\n    throw new Error(\"Filter JSON has a connection to a missing target block — repair or re-export\");\n  }\n  throw e;\n}","preventionTips":["Remove connections when removing blocks.","Validate inputBlock references before deserializing.","Re-export from the editor instead of manual JSON editing.","Keep block ids unique and stable within a file.","Prevent merging filters by naive JSON concatenation."],"tags":["smart-filters","deserialization","graph-integrity","validation"],"backgroundTag":"dangling-reference-in-graph","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}