{"record":{"id":"c1d9691e7c44741a","repo":"BabylonJS/Babylon.js","slug":"blocktype-must-be-defined","errorCode":null,"errorMessage":"blockType must be defined","messagePattern":"blockType must be defined","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/smartFilters/src/serialization/importCustomBlockDefinition.ts","lineNumber":60,"sourceCode":"        }\r\n\r\n        return blockDefinition;\r\n    }\r\n}\r\n\r\n/**\r\n * Converts a fragment shader .glsl file to an SerializedBlockDefinition instance for use\r\n * as a CustomShaderBlock. The .glsl file must contain certain annotations to be imported.\r\n * See readme.md for more information.\r\n * @param fragmentShader - The contents of the .glsl fragment shader file\r\n * @returns The serialized block definition\r\n */\r\nfunction ImportAnnotatedGlsl(fragmentShader: string): SerializedShaderBlockDefinition {\r\n    setLogger(Logger);\r\n    const fragmentShaderInfo = ParseFragmentShader(fragmentShader);\r\n\r\n    if (!fragmentShaderInfo.blockType) {\r\n        throw new Error(\"blockType must be defined\");\r\n    }\r\n\r\n    // Calculate the input connection points\r\n    const inputConnectionPoints: SerializedInputConnectionPointV1[] = [];\r\n    for (const uniform of fragmentShaderInfo.uniforms) {\r\n        // Add to input connection point list\r\n        const inputConnectionPoint: SerializedInputConnectionPointV1 = {\r\n            name: uniform.name,\r\n            type: uniform.type,\r\n            autoBind: uniform.properties?.autoBind as InputAutoBindV1,\r\n        };\r\n        if (inputConnectionPoint.type !== ConnectionPointType.Texture && uniform.properties?.default !== undefined) {\r\n            inputConnectionPoint.defaultValue = uniform.properties.default;\r\n        }\r\n        inputConnectionPoints.push(inputConnectionPoint);\r\n    }\r\n\r\n    return {\r","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/smartFilters/src/serialization/importCustomBlockDefinition.ts#L42-L78","documentation":"ImportAnnotatedGlsl parses an annotated GLSL fragment shader to derive a serialized shader block definition. The blockType is extracted from the shader's annotations; if parsing produces no blockType, the import aborts because every custom block must be registered under a unique block type. This is a validation of the shader source content itself.","triggerScenarios":"Calling ImportCustomBlockDefinition (or ImportAnnotatedGlsl directly) with a fragment shader string that lacks the blockType annotation — e.g. the special comment/directive declaring the block type was removed, misspelled, or the shader was written as plain GLSL without any Smart Filter annotations.","commonSituations":"Migrating plain Babylon shader code into a Smart Filter custom block, editing shader files with formatters that strip special comments, copy-pasting shaders without their header annotations.","solutions":["Add the blockType annotation to the fragment shader (the annotated-comment header ParseFragmentShader reads).","Check annotation spelling/format against the parser's expected syntax.","Confirm the annotation survives minification/formatters — keep it in a block comment the parser recognizes.","Ensure you are passing the fragment shader source, not a file path or a compiled program.","Re-export a working custom shader block from the editor to see a correct annotation example."],"exampleFix":"// before\nconst glsl = `uniform float amount; void main() {}`; // no annotations\n// after\nconst glsl = `//blocktype MyShaderBlock\nuniform float amount; void main() {}`; // annotation present per parser format","handlingStrategy":"validation","validationCode":"function validateShaderBlockType(fragmentShader) {\n  // mimic the annotated-GLSL convention: blockType must appear in the shader header\n  if (!/blockType\\s*[:=]?\\s*\\S+/i.test(fragmentShader)) {\n    throw new Error(\"Fragment shader is missing its blockType annotation\");\n  }\n}","typeGuard":"function isAnnotatedShader(src) {\n  return typeof src === \"string\" && /blocktype/i.test(src);\n}","tryCatchPattern":"try {\n  const def = ImportCustomBlockDefinition({ format: \"glsl\", fragmentShader });\n} catch (e) {\n  if (e.message === \"blockType must be defined\") {\n    throw new Error(\"GLSL source lacks the blockType annotation — add the annotated header\");\n  }\n  throw e;\n}","preventionTips":["Keep the blockType annotation comment at the top of every custom shader.","Configure formatters/minifiers to preserve the annotation comments.","Copy shaders from the editor export to guarantee correct annotation syntax.","Pass raw shader source text, not paths or compiled output.","Lint custom shaders for required annotations before import."],"tags":["smart-filters","glsl","serialization","custom-blocks","validation"],"backgroundTag":"missing-required-field","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}