{"record":{"id":"d29ef001caf9384a","repo":"BabylonJS/Babylon.js","slug":"consts-must-have-a-name-type-and-a-default-valu","errorCode":null,"errorMessage":"`Consts must have a name, type, and a default value: '${constLine}'`","messagePattern":"`Consts must have a name, type, and a default value: '(.+?)'`","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/smartFilters/src/utils/buildTools/shaderConverter.ts","lineNumber":215,"sourceCode":"            continue;\r\n        }\r\n\r\n        const annotation = JSON.parse(annotationJSON.replace(\"//\", \"\").trim()) as ConstMetadataAnnotation;\r\n\r\n        // If the annotation doesn't have a \"property\" field, treat it as a regular const\r\n        if (!annotation.property) {\r\n            continue;\r\n        }\r\n\r\n        const constLine = matches[2];\r\n\r\n        if (!constLine) {\r\n            throw new Error(\"Const line not found\");\r\n        }\r\n\r\n        const constLineMatches = new RegExp(/^const\\s+(\\w+)\\s+(\\w+)\\s*=\\s*([^\\s;]+)\\s*;?\\s*$/gm).exec(constLine);\r\n        if (!constLineMatches || constLineMatches.length < 4) {\r\n            throw new Error(`Consts must have a name, type, and a default value: '${constLine}'`);\r\n        }\r\n        const type = constLineMatches[1];\r\n        const friendlyName = constLineMatches[2];\r\n        const defaultValue = constLineMatches[3];\r\n\r\n        if (!friendlyName) {\r\n            throw new Error(`Consts must have a name: '${constLine}'`);\r\n        }\r\n        if (defaultValue === null) {\r\n            throw new Error(`Consts must have a value: '${constLine}'`);\r\n        }\r\n\r\n        const constProperty: ConstPropertyMetadata | null =\r\n            type === \"float\"\r\n                ? {\r\n                      name: DecorateSymbol(friendlyName),\r\n                      friendlyName,\r\n                      type,\r","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/smartFilters/src/utils/buildTools/shaderConverter.ts#L197-L233","documentation":"After locating an annotated const line, the converter parses it with /^const\\s+(\\w+)\\s+(\\w+)\\s*=\\s*([^\\s;]+)\\s*;?\\s*$/. If the line does not match this exact 'const TYPE NAME = VALUE;' shape (or does not span a single line), this error names the offending line. The parser requires all three tokens plus a default value.","triggerScenarios":"ParseFragmentShader encounters a property-annotated const written across multiple lines (`const float x =\n 0.5;`), with an unusual declaration form (`const float x=0.5` no spaces is fine, but `const vec3 x = vec3(0.);` — value with spaces/parens containing whitespace — breaks the [^\\s;]+ value match), or missing the initializer entirely.","commonSituations":"Multi-line const initializers; vector/matrix consts written with spaces inside the initializer; consts like `const float PI = 3.14159 // radians;` with trailing comments; non-float consts such as vec2/vec3 which the format also can't express.","solutions":["Rewrite the const on a single line as `const <type> <name> = <value>;` with no internal whitespace in the value.","Only use simple literal defaults (numbers) for property consts — the parser only supports float consts anyway.","Remove trailing comments from the const line.","If the value is a vector type, drop the property annotation or restructure as separate float consts."],"exampleFix":"// before\nconst vec3 tint =\n    vec3(1.0, 1.0, 1.0);\n// after\nconst float tintR = 1.0;\nconst float tintG = 1.0;\nconst float tintB = 1.0;","handlingStrategy":"validation","validationCode":"const bad = [...shader.matchAll(/\\/\\/\\s*\\{.*\\}\\s*(?:\\r?\\n)+(const .*)/gm)].map(m => m[1]).filter(l => !/^const\\s+\\w+\\s+\\w+\\s*=\\s*[^\\s;]+\\s*;?\\s*$/.test(l));\nif (bad.length) throw new Error(`Malformed property const lines: ${bad.join(\" | \")}`);","typeGuard":"function isSingleLineConst(line: string): boolean {\n  return /^const\\s+\\w+\\s+\\w+\\s*=\\s*[^\\s;]+\\s*;?\\s*$/.test(line);\n}","tryCatchPattern":"try {\n  const info = ParseFragmentShader(blockName, namespace, shader);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith(\"Consts must have a name, type, and a default value\")) {\n    console.error(\"Fix this const line to match: const <type> <name> = <value>;\", e.message);\n  } else throw e;\n}","preventionTips":["Write property consts on exactly one line with a simple literal value.","Avoid multi-line initializers and trailing comments on property const lines.","Remember only `const float name = value;` form is parseable.","Add a pre-commit regex check on shader assets."],"tags":["shader","parsing","glsl","syntax"],"backgroundTag":"shader-const-syntax-invalid","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}