{"record":{"id":"86c97338ac71296c","repo":"pestphp/pest","slug":"the-beforeall-hook-may-not-be-used-inside-a-des","errorCode":null,"errorMessage":"The [beforeAll] hook may not be used inside a [describe] block. Please move it to the top level of [%s].","messagePattern":"The \\[beforeAll\\] hook may not be used inside a \\[describe\\] block\\. Please move it to the top level of \\[(.+?)\\]\\.","errorType":"exception","errorClass":"BeforeAllWithinDescribe","httpStatus":null,"severity":"error","filePath":"src/Functions.php","lineNumber":47,"sourceCode":"    /**\n     * @template TValue\n     *\n     * @param  TValue|null  $value\n     * @return Expectation<TValue|null>\n     */\n    function expect(mixed $value = null): Expectation\n    {\n        return new Expectation($value);\n    }\n}\n\nif (! function_exists('beforeAll')) {\n    function beforeAll(Closure $closure): void\n    {\n        if (DescribeCall::describing() !== []) {\n            $filename = Backtrace::testFile();\n\n            throw new BeforeAllWithinDescribe($filename);\n        }\n\n        TestSuite::getInstance()->beforeAll->set($closure);\n    }\n}\n\nif (! function_exists('beforeEach')) {\n    /**\n     * @param-closure-this TestCall  $closure\n     */\n    function beforeEach(?Closure $closure = null): BeforeEachCall\n    {\n        $filename = Backtrace::testFile();\n\n        return new BeforeEachCall(TestSuite::getInstance(), $filename, $closure);\n    }\n}\n","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/pestphp/pest/blob/1af74a215c3a89bc7a44fc6f9322e369eaad2423/src/Functions.php#L29-L65","documentation":"beforeAll() registers a once-per-file hook on the TestSuite, but inside a describe() block Pest has no scoping for suite-level hooks, so Functions.php throws BeforeAllWithinDescribe, naming the file. The rule: beforeAll must sit at the top level of the test file. (beforeEach inside describe is fine — only the All variants are restricted.)","triggerScenarios":"Calling beforeAll(function () { ... }) anywhere inside a describe('...', function () { ... }) block; nesting beforeAll in group helpers; moving top-level hooks into a describe during a refactor to 'scope' them.","commonSituations":"Reorganizing a test file to group tests and dragging hooks along; assuming Jasmine/Jest semantics where beforeAll inside describe is allowed; trying to scope expensive setup to one describe block.","solutions":["Move the beforeAll() call to the top level of the file (outside any describe).","If the setup only serves that group, use beforeEach() inside the describe instead — it is allowed and scoped.","For per-group one-time setup, restructure: split the describe into its own test file, or perform setup lazily (once-flag inside beforeEach, or memoized helper)."],"exampleFix":"// before\ndescribe('billing', function () {\n    beforeAll(fn () => $this->seed = seedDb()); // throws\n    it('charges', fn () => ...);\n});\n// after\nbeforeAll(fn () => seedDb());\ndescribe('billing', function () {\n    beforeEach(fn () => cleanTables());\n    it('charges', fn () => ...);\n});","handlingStrategy":"validation","validationCode":"// cheap lint before running the suite:\nforeach (glob('tests/**/*Test.php') ?: [] as $file) {\n    $tokens = token_get_all(file_get_contents($file));\n    $depth = 0; $line = 0;\n    foreach ($tokens as $i => $t) {\n        $line = is_array($t) ? $t[2] : $line;\n        // simplified: flag beforeAll when a describe() is currently open\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep all beforeAll/afterAll calls at the top of the file; use beforeEach/afterEach inside describe blocks.","During refactors that introduce describe(), move All-hooks out of the block deliberately.","In code review, check hook placement whenever a describe() wrapper is added."],"tags":["pest","hooks","before-all","describe","scope"],"backgroundTag":"hook-in-invalid-scope","analyzedSha":"1af74a215c3a89bc7a44fc6f9322e369eaad2423","analyzedAt":"2026-08-21T02:16:38.132Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}