{"record":{"id":"eec081be44f0fd05","repo":"BabylonJS/Babylon.js","slug":"expected-identifier-for-node-name-got-identtok","errorCode":null,"errorMessage":"Expected identifier for node name, got '${identTok.value}' at pos ${identTok.pos}","messagePattern":"Expected identifier for node name, got '(.+?)' at pos (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/loaders/src/FBX/parsers/fbxAsciiParser.ts","lineNumber":247,"sourceCode":"    }\r\n\r\n    private isIdentChar(ch: string): boolean {\r\n        return this.isIdentStart(ch) || this.isDigit(ch) || ch === \"|\";\r\n    }\r\n}\r\n\r\n// ── Node Parsing ───────────────────────────────────────────────────────────────\r\n\r\nfunction parseNodeFromTokens(tokenizer: Tokenizer): FBXNode | null {\r\n    const nameTok = tokenizer.peek();\r\n    if (nameTok.type === TokenType.CloseBrace || nameTok.type === TokenType.EOF) {\r\n        return null;\r\n    }\r\n\r\n    // Node name\r\n    const identTok = tokenizer.next();\r\n    if (identTok.type !== TokenType.Identifier) {\r\n        throw new Error(`Expected identifier for node name, got '${identTok.value}' at pos ${identTok.pos}`);\r\n    }\r\n    const name = identTok.value;\r\n    tokenizer.expect(TokenType.Colon);\r\n\r\n    // Parse properties until we hit '{' or end-of-line content\r\n    const properties: FBXProperty[] = [];\r\n    const children: FBXNode[] = [];\r\n\r\n    // Check for array shorthand: *count { a: ... }\r\n    let peek = tokenizer.peek();\r\n    if (peek.type === TokenType.Star) {\r\n        // Array node like \"Vertices: *25959 {\"\r\n        tokenizer.next(); // consume *\r\n        const countTok = tokenizer.expect(TokenType.Number);\r\n        const count = parseInt(countTok.value);\r\n        tokenizer.expect(TokenType.OpenBrace);\r\n\r\n        // Expect \"a:\" followed by comma-separated values\r","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/FBX/parsers/fbxAsciiParser.ts#L229-L265","documentation":"The ASCII FBX parser's token-driven node reader expects a node name token (an Identifier) after whitespace; whatever token it found (a number, punctuation, or EOF artifact) cannot be a valid FBX node name, so it aborts with the offending token value and position. This guards against structurally malformed ASCII FBX text rather than silently producing a node with a garbage name.","triggerScenarios":"Calling the loader's parse/entry functions (via `node`/`child` in parseNodeFromTokens) on ASCII FBX text where the token after optional properties is not an identifier — e.g. a stray number, ':' or '{' where 'Model: 12345' expects a name, or a syntax error earlier in the file shifted token boundaries.","commonSituations":"Hand-edited or truncated .fbx ASCII files; files exported by tools producing non-standard ASCII FBX; copying/pasting FBX snippets with missing node names; files that are actually binary FBX being fed through the ASCII parser path.","solutions":["Open the file at the reported pos and fix the malformed node so it reads `NodeType: \"Name\" { ... }`","Re-export the FBX from the source DCC tool (Blender/Maya/3ds Max) instead of hand-editing","Check the file is actually ASCII FBX (starts with `; FBX ...` or `FBXHeaderExtension:`), not binary — binary files must go through the binary parser","Verify no earlier parse error shifted tokenization; inspect tokens preceding pos"],"exampleFix":"// before (malformed ASCII FBX)\nModel: {\n// after\nModel: \"Cube\" {","handlingStrategy":"validation","validationCode":"function isLikelyAsciiFbx(text) {\n  const head = text.slice(0, 512);\n  if (/Kaydara FBX Binary/.test(head)) return false;\n  // every node line should look like: Name: ... or Name: \"Name\" {\n  return /^[A-Za-z_][\\w ]*:/m.test(head);\n}\nif (!isLikelyAsciiFbx(fbxText)) throw new Error(\"Not ASCII FBX\");","typeGuard":null,"tryCatchPattern":"try {\n  const doc = parseAsciiFbx(text);\n} catch (e) {\n  if (e.message.includes(\"Expected identifier for node name\")) {\n    const m = e.message.match(/pos (\\d+)/);\n    console.error(`Malformed FBX near char ${m?.[1]}; fix the node or re-export the file`);\n  } else throw e;\n}","preventionTips":["Never hand-edit ASCII FBX; re-export from the DCC tool instead","Detect binary vs ASCII FBX by magic bytes before choosing a parser","Run new/converted files through the parser once in CI with a fixture set","When editing is unavoidable, keep the `Type: \"Name\" {` shape intact"],"tags":["fbx","parser","ascii","syntax-error","malformed-file"],"backgroundTag":"fbx-parse-syntax-error","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}