Skip to content

BadMethodCallException: Call to undefined method errorHeadline when rendering 404 Antlers template outside Statamic's Cascade #14167

@stephenmeehanuk

Description

@stephenmeehanuk

I intermittently get this error in Laravel Nightwatch. Is this something that could be fixed with an update?

BadMethodCallException: Call to undefined method errorHeadline.

The Problem:

I was getting a BadMethodCallException: Call to undefined method errorHeadline in production, triggered by bots/scanners hitting the Livewire update endpoint directly (POST to /livewire-{hash}/update without the X-Livewire header).

The 404 error template (resources/views/errors/404.antlers.html) was pulling content from a 404 global set using the standard colon syntax:

{{ 404:error_headline }}
{{ 404:error_text }}

Root Cause:

Livewire registers its update route with only the web middleware group , it doesn't include Statamic's SwapExceptionHandler middleware, which is what hydrates the Cascade with global set data.

When Livewire's RequireLivewireHeaders middleware detects a request without the X-Livewire header, it calls abort(404). Laravel's default exception handler then renders the errors/404.antlers.html view through the Antlers engine, but without the Cascade being hydrated.

Without the Cascade, the Antlers runtime can't resolve 404 as a global set handle. It falls through to treating 404 as a tag name and attempts to call errorHeadline() as a method on Statamic\Tags\Tags via __call() — which throws BadMethodCallException.

The ?? (null coalescence) operator doesn't help either {{ 404:error_headline ?? 'fallback' }} still throws, because the exception happens during tag resolution before the fallback operator evaluates.

How to Reproduce:

From the browser console on any page with a valid session:

const token = decodeURIComponent(
  document.cookie.split('; ').find(c => c.startsWith('XSRF-TOKEN='))?.split('=')[1]
);
fetch('/livewire-YOUR_HASH_HERE/update', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', 'X-XSRF-TOKEN': token }
  // deliberately no X-Livewire header
}).then(r => r.text()).then(console.log)

You can find your Livewire endpoint hash with php artisan route:list | grep livewire.

Fix:

I hardcoded the content in the 404 template, removing all {{ 404:... }} references. The global set colon syntax ({{ handle:field }}) relies on the Cascade and can't be used safely in error templates that may be rendered outside Statamic's rendering pipeline.

Takeaway:

If you're using Antlers for your error templates (resources/views/errors/*.antlers.html), be aware that they can be rendered by Laravel's exception handler without Statamic's Cascade. Avoid global set references using the colon syntax ({{ global_handle:field }}). Either hardcode the values or use a Blade template with PHP to load globals via Statamic\Facades\GlobalSet::findByHandle().

I asked Claude if there's a fix? It suggested:

Statamic could hydrate the Cascade in the exception handler

Statamic's SwapExceptionHandler middleware is what sets up the Cascade for front-end routes. But routes outside Statamic's middleware stack (like Livewire's) use Laravel's default exception handler, which renders the Antlers 404 view without the Cascade. Statamic could register a global exception renderer (via Exceptions::render() in bootstrap/app.php or a service provider) that ensures the Cascade is hydrated before rendering any Antlers error template, regardless of which middleware stack the request went through.

Environment
Application Name: Statamic
Laravel Version: 12.53.0
PHP Version: 8.4.18
Composer Version: 2.9.5
Environment: local
Debug Mode: OFF
URL: website.test
Maintenance Mode: OFF
Timezone: America/New_York
Locale: en

Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: CACHED

Drivers
Broadcasting: log
Cache: redis
Database: sqlite
Logs: stack / single
Mail: smtp
Queue: sync
Session: redis

Storage
public/storage: NOT LINKED

Livewire
Livewire: v4.2.1

Statamic
Addons: 5
Sites: 1
Stache Watcher: Enabled
Static Caching: Disabled
Version: 5.73.11 PRO

Statamic Addons
marcorieser/statamic-live-search: 3.1.1
marcorieser/statamic-livewire: 5.2.1
statamic/collaboration: 1.0.1
statamic/importer: 1.9.0
visuellverstehen/statamic-anchor-navigation: 1.0.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions