dianping/cat · error · Error

__halt_compiler() can only be used from the outermost scope

Error message

__halt_compiler() can only be used from the outermost scope

What it means

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.

Source

Thrown at cat-home/src/main/webapp/assets/js/editor/worker-php.js:3579

PHP.Parser.prototype.yyn25 = function ( attributes ) {
     this.yyval = []; 
};

PHP.Parser.prototype.yyn26 = function ( attributes ) {
     this.yyval = this.yyastk[ this.stackPos-(1-1) ]; 
};

PHP.Parser.prototype.yyn27 = function ( attributes ) {
     this.yyval = this.yyastk[ this.stackPos-(1-1) ]; 
};

PHP.Parser.prototype.yyn28 = function ( attributes ) {
     this.yyval = this.yyastk[ this.stackPos-(1-1) ]; 
};

PHP.Parser.prototype.yyn29 = function ( attributes ) {
     throw new Error('__halt_compiler() can only be used from the outermost scope'); 
};

PHP.Parser.prototype.yyn30 = function ( attributes ) {
     this.yyval = this.yyastk[ this.stackPos-(3-2) ]; 
};

PHP.Parser.prototype.yyn31 = function ( attributes ) {
     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); 
};

PHP.Parser.prototype.yyn32 = function ( attributes ) {
     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); 
};

PHP.Parser.prototype.yyn33 = function ( attributes ) {
     this.yyval = this.Node_Stmt_While(this.yyastk[ this.stackPos-(5-3) ], this.yyastk[ this.stackPos-(5-5) ], attributes); 
};

View on GitHub (pinned to e815e74d4c)

Solutions

  1. Move __halt_compiler(); to the outermost scope of the PHP file (no enclosing function/class/block).
  2. If you don't need it, delete the call — it exists only to let a script embed data after the PHP block.
  3. Remember everything after __halt_compiler(); is treated as literal data, so it must be the last executable statement.

Example fix

// before
<?php
function boot() {
    __halt_compiler();
}

// after
<?php
function boot() {
    // ...
}
__halt_compiler();
Defensive patterns

Strategy: validation

Validate before calling

// Static check before sending to the worker: __halt_compiler must be at depth 0.
function haltCompilerAtTopLevel(src) {
  let depth = 0;
  for (const line of src.split('\n')) {
    for (const ch of line) {
      if (ch === '{' || ch === '(') depth++;
      if (ch === '}' || ch === ')') depth--;
    }
    if (/__halt_compiler\s*\(/.test(line) && depth !== 0) return false;
  }
  return true;
}

Try / catch

try {
  parser.parse(src);
} catch (ex) {
  if (/__halt_compiler/.test(ex.message)) {
    annotate({ line: parser.startAttributes && parser.startAttributes.startLine, message: ex.message });
  } else throw ex;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14). Data as JSON: /api/errors/04dc88b06381ea72. Report an issue: GitHub.