{"record":{"id":"94bc41436ce4a379","repo":"mozilla/pdf.js","slug":"invalid-token-in-func-declaration","errorCode":null,"errorMessage":"Invalid token in func declaration.","messagePattern":"Invalid token in func declaration\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/core/xfa/formcalc_parser.js","lineNumber":1083,"sourceCode":"      throw new Error(Errors.var);\n    }\n\n    const identifier = tok.value;\n\n    tok = this.lexer.next();\n    if (tok.id !== TOKEN.assign) {\n      return [tok, new VarDecl(identifier, null)];\n    }\n\n    const [tok1, expr] = this.parseSimpleExpr();\n    return [tok1, new VarDecl(identifier, expr)];\n  }\n\n  parseFuncDecl() {\n    // 'func' Identifier ParameterList 'do' ExpressionList 'endfunc'.\n    let tok = this.lexer.next();\n    if (tok.id !== TOKEN.identifier) {\n      throw new Error(Errors.func);\n    }\n\n    const identifier = tok.value;\n    const params = this.parseParamList();\n\n    tok = this.lexer.next();\n    if (tok.id !== TOKEN.do) {\n      throw new Error(Errors.func);\n    }\n\n    const [tok1, body] = this.parseExprList();\n\n    tok = tok1 || this.lexer.next();\n    if (tok.id !== TOKEN.endfunc) {\n      throw new Error(Errors.func);\n    }\n\n    return [null, new FuncDecl(identifier, params, body)];","sourceCodeStart":1065,"sourceCodeEnd":1101,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/xfa/formcalc_parser.js#L1065-L1101","documentation":"Thrown by Parser.parseFuncDecl() when, immediately after the 'func' keyword, the next token is not an identifier (TOKEN.identifier). FormCalc function grammar is 'func Identifier ParamList do ExprList endfunc', so 'func' must be followed by the function name first.","triggerScenarios":"A FormCalc script like 'func () do ... endfunc' or 'func 42 (...) do ...' where the function name identifier is missing. Reached while parsing an XFA form script that declares a function.","commonSituations":"Typo dropping the function name; using a reserved word as a function name; truncated/corrupted script bytes after 'func'; generator emitting 'func' then '(' directly.","solutions":["Place a valid identifier (the function name) immediately after 'func'.","Confirm the name is not a FormCalc keyword or builtin that the lexer would not classify as a plain identifier.","Re-author the function declaration in a FormCalc tool and re-serialize the XFA packet.","Catch the parser error at XFA binding and skip the malformed function."],"exampleFix":"// before\nfunc (a) do a+1 endfunc\n// after\nfunc inc(a) do a+1 endfunc","handlingStrategy":"validation","validationCode":"// Reject 'func' not followed by an identifier.\nfunction validFuncNames(src) {\n  return !/\\bfunc\\b(?!\\s+[A-Za-z_][A-Za-z0-9_]*)/.test(src);\n}","typeGuard":null,"tryCatchPattern":"try {\n  bindFormCalcScript(xfaNode, src);\n} catch (e) {\n  if (e instanceof Error && /func declaration/.test(e.message)) {\n    console.warn(\"Malformed FormCalc func declaration; skipping\", e.message);\n    return;\n  }\n  throw e;\n}","preventionTips":["Always provide a function name identifier right after 'func'.","Avoid reserved/builtin names as function names.","Lint 'func' declarations before binding."],"tags":["xfa","formcalc","parser","syntax","func"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}