{"record":{"id":"04dc88b06381ea72","repo":"dianping/cat","slug":"halt-compiler-can-only-be-used-from-the-outerm","errorCode":null,"errorMessage":"__halt_compiler() can only be used from the outermost scope","messagePattern":"__halt_compiler\\(\\) can only be used from the outermost scope","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cat-home/src/main/webapp/assets/js/editor/worker-php.js","lineNumber":3579,"sourceCode":"\nPHP.Parser.prototype.yyn25 = function ( attributes ) {\n     this.yyval = []; \n};\n\nPHP.Parser.prototype.yyn26 = function ( attributes ) {\n     this.yyval = this.yyastk[ this.stackPos-(1-1) ]; \n};\n\nPHP.Parser.prototype.yyn27 = function ( attributes ) {\n     this.yyval = this.yyastk[ this.stackPos-(1-1) ]; \n};\n\nPHP.Parser.prototype.yyn28 = function ( attributes ) {\n     this.yyval = this.yyastk[ this.stackPos-(1-1) ]; \n};\n\nPHP.Parser.prototype.yyn29 = function ( attributes ) {\n     throw new Error('__halt_compiler() can only be used from the outermost scope'); \n};\n\nPHP.Parser.prototype.yyn30 = function ( attributes ) {\n     this.yyval = this.yyastk[ this.stackPos-(3-2) ]; \n};\n\nPHP.Parser.prototype.yyn31 = function ( attributes ) {\n     this.yyval = this.Node_Stmt_If(this.yyastk[ this.stackPos-(7-3) ], {'stmts':  Array.isArray(this.yyastk[ this.stackPos-(7-5) ]) ? this.yyastk[ this.stackPos-(7-5) ] : [this.yyastk[ this.stackPos-(7-5) ]], 'elseifs':  this.yyastk[ this.stackPos-(7-6) ], 'Else':  this.yyastk[ this.stackPos-(7-7) ]}, attributes); \n};\n\nPHP.Parser.prototype.yyn32 = function ( attributes ) {\n     this.yyval = this.Node_Stmt_If(this.yyastk[ this.stackPos-(10-3) ], {'stmts':  this.yyastk[ this.stackPos-(10-6) ], 'elseifs':  this.yyastk[ this.stackPos-(10-7) ], 'else':  this.yyastk[ this.stackPos-(10-8) ]}, attributes); \n};\n\nPHP.Parser.prototype.yyn33 = function ( attributes ) {\n     this.yyval = this.Node_Stmt_While(this.yyastk[ this.stackPos-(5-3) ], this.yyastk[ this.stackPos-(5-5) ], attributes); \n};\n","sourceCodeStart":3561,"sourceCodeEnd":3597,"githubUrl":"https://github.com/dianping/cat/blob/e815e74d4c2dd74edac831241f1253fcc7d25381/cat-home/src/main/webapp/assets/js/editor/worker-php.js#L3561-L3597","documentation":"A semantic reduce action in the generated PHP parser (worker-php.js:5653-region table; the action yyn29 at line 3577-3580). The grammar accepts __halt_compiler() only via a special outermost-scope production; if it is reduced through the ordinary statement rule instead, the reduce action throws this plain Error. It mirrors PHP itself, where __halt_compiler() is only allowed at the top level of a file.","triggerScenarios":"Writing __halt_compiler() anywhere but the outermost scope: inside a function, method, if/loop block, or closure — e.g. 'function f() { __halt_compiler(); }'. The parser reduces the inner-statement production, hits yyn29, and throws at line 3579.","commonSituations":"Template/PHAR tooling code where __halt_compiler is used to embed binary data, refactoring moves the call into a function, or copy-pasting installer stubs into class methods. Also hit while typing in the ACE PHP editor before the call is moved to file scope.","solutions":["Move __halt_compiler(); to the outermost scope of the PHP file (no enclosing function/class/block).","If you don't need it, delete the call — it exists only to let a script embed data after the PHP block.","Remember everything after __halt_compiler(); is treated as literal data, so it must be the last executable statement."],"exampleFix":"// before\n<?php\nfunction boot() {\n    __halt_compiler();\n}\n\n// after\n<?php\nfunction boot() {\n    // ...\n}\n__halt_compiler();","handlingStrategy":"validation","validationCode":"// Static check before sending to the worker: __halt_compiler must be at depth 0.\nfunction haltCompilerAtTopLevel(src) {\n  let depth = 0;\n  for (const line of src.split('\\n')) {\n    for (const ch of line) {\n      if (ch === '{' || ch === '(') depth++;\n      if (ch === '}' || ch === ')') depth--;\n    }\n    if (/__halt_compiler\\s*\\(/.test(line) && depth !== 0) return false;\n  }\n  return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n  parser.parse(src);\n} catch (ex) {\n  if (/__halt_compiler/.test(ex.message)) {\n    annotate({ line: parser.startAttributes && parser.startAttributes.startLine, message: ex.message });\n  } else throw ex;\n}","preventionTips":["Keep __halt_compiler(); as the last statement at file scope, never inside functions/blocks.","When refactoring installers, remember moving it into a function breaks both this parser and PHP itself.","Treat everything after the call as embedded data — no PHP after it."],"tags":["php","ace-editor","parser","scope","halt-compiler"],"backgroundTag":null,"analyzedSha":"e815e74d4c2dd74edac831241f1253fcc7d25381","analyzedAt":"2026-08-14T14:22:34.512Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}