{"record":{"id":"3b045179af334b08","repo":"BabylonJS/Babylon.js","slug":"block-connection-inputblock-does-not-have-a-co","errorCode":null,"errorMessage":"`Block ${connection.inputBlock} does not have a connection point named ${connection.inputConnectionPoint}`","messagePattern":"`Block (.+?) does not have a connection point named (.+?)`","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/smartFilters/src/serialization/smartFilterDeserializer.ts","lineNumber":111,"sourceCode":"\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\n        blockTypesWhichCouldNotBeDeserialized: string[],\r\n        blockIdMap: Map<number, BaseBlock>,\r\n        blockNameMap: Map<string, BaseBlock>\r\n    ): Promise<void> {\r\n        let newBlock: Nullable<BaseBlock> = null;\r","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/smartFilters/src/serialization/smartFilterDeserializer.ts#L93-L129","documentation":"The target block exists, but no input connection point on it matches connection.inputConnectionPoint (or the found point is not a valid object). Connections must land on a declared input endpoint; a mismatch means the serialized graph references an input the block does not provide.","triggerScenarios":"connection.inputConnectionPoint does not equal any of targetBlock.inputs' names — input renamed in a block refactor, typo in JSON, or connection copied from a different block type with different input names.","commonSituations":"Custom block inputs renamed between versions, hand-edited filter files, mixing blocks serialized from different filter versions, block type resolved to a different class than when serialized.","solutions":["Correct inputConnectionPoint to the block's actual input name (check the block class's inputs list).","Re-export the filter from the current tooling so endpoint names are regenerated.","Update the block implementation to retain the legacy input name or write a migration for old serialized names.","Verify the resolved block type is the intended one (same lookup caveat as error 866).","Pre-validate connections against block input declarations before calling the deserializer."],"exampleFix":"// before\n{ \"inputBlock\": \"GrayScale\", \"inputConnectionPoint\": \"texture\", ... } // actual input \"input\"\n// after\n{ \"inputBlock\": \"GrayScale\", \"inputConnectionPoint\": \"input\", ... }","handlingStrategy":"validation","validationCode":"function validateTargetConnectionPoints(serialized, blockRegistry) {\n  for (const c of serialized.connections) {\n    const block = serialized.blocks.find((b) => b.name === c.inputBlock || b.uniqueId === c.inputBlock);\n    if (block && !blockRegistry.getInputs(block).includes(c.inputConnectionPoint)) {\n      throw new Error(`Block ${c.inputBlock} has no input '${c.inputConnectionPoint}'`);\n    }\n  }\n}","typeGuard":"function hasInput(block, name) {\n  return block?.inputs?.some((i) => i.name === name) ?? false;\n}","tryCatchPattern":"try {\n  const filter = await SmartFilterDeserializer.DeserializeAsync(runtime, container, json);\n} catch (e) {\n  const m = e.message.match(/Block (.+) does not have a connection point named (.+)/);\n  if (m) throw new Error(`Fix input endpoint: block '${m[1]}' has no input '${m[2]}'`);\n  throw e;\n}","preventionTips":["Verify input names against block class declarations after any refactor.","Regenerate filter files with current tooling after block version bumps.","Write endpoint-name migrations for legacy files.","Do not reuse connection entries across block types.","Run connection validation in CI for filter assets."],"tags":["smart-filters","deserialization","graph-integrity","connection-points"],"backgroundTag":"dangling-reference-in-graph","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}