{"record":{"id":"4f603ca4571929b7","repo":"BabylonJS/Babylon.js","slug":"cannot-register-an-input-connection-point-with-no","errorCode":null,"errorMessage":"Cannot register an input connection point with no internal connection points","messagePattern":"Cannot register an input connection point with no internal connection points","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/smartFilters/src/blockFoundation/aggregateBlock.ts","lineNumber":127,"sourceCode":"            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Registers an input connection from the internal graph as an input of the aggregated graph.\r\n     * @param name - The name of the exposed input connection point\r\n     * @param internalConnectionPoints - The input connection points in the inner graph to wire up to the new subfilter input\r\n     * @param defaultValue - The default value to use for the input connection point\r\n     * @returns the connection point referencing the input block\r\n     */\r\n    protected _registerSubfilterInput<U extends ConnectionPointType>(\r\n        name: string,\r\n        internalConnectionPoints: ConnectionPoint<U>[],\r\n        defaultValue: Nullable<RuntimeData<U>> = null\r\n    ): ConnectionPoint<U> {\r\n        const type = internalConnectionPoints[0]?.type;\r\n        if (type === undefined) {\r\n            throw new Error(\"Cannot register an input connection point with no internal connection points\");\r\n        }\r\n        const externalInputConnectionPoint = this._registerInput(name, type, defaultValue);\r\n\r\n        this._aggregatedInputs.push([internalConnectionPoints, externalInputConnectionPoint]);\r\n\r\n        return externalInputConnectionPoint;\r\n    }\r\n\r\n    /**\r\n     * Registers an output connection point from the internal graph as an output of the aggregated graph.\r\n     * @param name - The name of the exposed output connection point\r\n     * @param internalConnectionPoint - The output connection point in the inner graph to expose as an output on the aggregate block\r\n     * @returns the connection point referencing the output connection point\r\n     */\r\n    protected _registerSubfilterOutput<U extends ConnectionPointType>(name: string, internalConnectionPoint: ConnectionPoint<U>): ConnectionPoint<U> {\r\n        const externalOutputConnectionPoint = this._registerOutput(name, internalConnectionPoint.type);\r\n\r\n        this._aggregatedOutputs.push([internalConnectionPoint, externalOutputConnectionPoint]);\r","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/smartFilters/src/blockFoundation/aggregateBlock.ts#L109-L145","documentation":"_registerSubfilterInput derives the external input's connection type from the first internal connection point. Registering an input with an empty internalConnectionPoints array leaves the type undefined, so the constructor throws. This is a programming error in the aggregate block's setup.","triggerScenarios":"Calling _registerSubfilterInput (directly or via aggregate block constructors) with internalConnectionPoints: [], e.g. after filtering out all candidate connection points, or before the inner filter's blocks have created their inputs.","commonSituations":"Building a CustomAggregateBlock whose inner filter has no matching inputs; conditional code that collects connection points and can produce an empty list; refactoring that renamed inputs so the lookup returns nothing.","solutions":["Ensure the internal connection points array is non-empty before registering (guard or assert length > 0).","Fix the lookup/filter that builds internalConnectionPoints so it actually matches inner block inputs.","Skip registering the external input when there is nothing to aggregate, if that is valid for your block.","Check the inner Smart Filter was fully constructed before the aggregate block's registration code runs."],"exampleFix":"// before\nblock._registerSubfilterInput(\"input\", innerPoints.filter(p => p.type === t));\n// after\nconst pts = innerPoints.filter(p => p.type === t);\nif (pts.length > 0) block._registerSubfilterInput(\"input\", pts);","handlingStrategy":"validation","validationCode":"if (internalConnectionPoints.length === 0) {\n    throw new Error('refusing to register subfilter input: no internal connection points');\n}\nblock._registerSubfilterInput(name, internalConnectionPoints);","typeGuard":"function hasPoints<U extends ConnectionPointType>(pts: ConnectionPoint<U>[]): pts is [ConnectionPoint<U>, ...ConnectionPoint<U>[]] {\n    return pts.length > 0;\n}","tryCatchPattern":"try {\n    registerAggregateInputs(block, collected);\n} catch (e) {\n    if (e instanceof Error && e.message.includes('no internal connection points')) {\n        // log which input name produced an empty list and fix the lookup\n    } else throw e;\n}","preventionTips":["Assert non-empty internal connection point arrays at collection time.","Verify inner filter input names/types before constructing aggregate blocks.","Keep the inner filter fully constructed before registration runs."],"tags":["smart-filters","connection-points","constructor"],"backgroundTag":"empty-connection-point-list","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}