Skip to content

Files fieldtype fieldRules() crashes on Closure validation rules (v6.7.0+) #14313

@jasonbaciulis

Description

@jasonbaciulis

Bug description

The fieldRules() method added to Statamic\Fieldtypes\Files in v6.7.0 assumes all validation rules are strings, but Closure-based rules are valid Laravel validation rules. When a blueprint defines a Closure rule on a files field (e.g. the Importer addon does this), calling Str::before($rule, ':') on a Closure triggers a TypeError.

The error: strstr(): Argument #1 ($haystack) must be of type string, Closure given

The fix would be a type guard in src/Fieldtypes/Files.php line 72:

return collect(parent::fieldRules())->map(function ($rule) use ($classes) {
    if (! is_string($rule)) {
        return $rule;
    }

    $name = Str::before($rule, ':');
    // ...

This worked in v6.6.3 because Files didn't have a fieldRules() override.

How to reproduce

  1. Install statamic/importer (^2.0)
  2. Upgrade to statamic/cms v6.7.0 or v6.7.1
  3. Navigate to CP > Utilities > Import
  4. Page crashes with TypeError

Logs

[2026-03-20 16:28:41] local.ERROR: strstr(): Argument #1 ($haystack) must be of type string, Closure given {"userId":1,"exception":"[object] (TypeError(code: 0): strstr(): Argument #1 ($haystack) must be of type string, Closure given at /var/www/html/vendor/laravel/framework/src/Illuminate/Support/Str.php:159)
[stacktrace]
#0 /var/www/html/vendor/laravel/framework/src/Illuminate/Support/Str.php(159): strstr(Object(Closure), ':', true)
#1 /var/www/html/vendor/statamic/cms/src/Support/Str.php(360): Illuminate\\Support\\Str::before(Object(Closure), ':')
#2 /var/www/html/vendor/statamic/cms/src/Fieldtypes/Files.php(73): Statamic\\Support\\Str::__callStatic('before', Array)
#3 [internal function]: Statamic\\Fieldtypes\\Files->{closure:Statamic\\Fieldtypes\\Files::fieldRules():72}(Object(Closure), 2)
#4 /var/www/html/vendor/laravel/framework/src/Illuminate/Collections/Arr.php(841): array_map(Object(Closure), Array, Array)
#5 /var/www/html/vendor/laravel/framework/src/Illuminate/Collections/Collection.php(829): Illuminate\\Support\\Arr::map(Array, Object(Closure))
#6 /var/www/html/vendor/statamic/cms/src/Fieldtypes/Files.php(72): Illuminate\\Support\\Collection->map(Object(Closure))
#7 /var/www/html/vendor/statamic/cms/src/Fields/Field.php(142): Statamic\\Fieldtypes\\Files->fieldRules()
#8 /var/www/html/vendor/statamic/cms/src/Fields/Field.php(177): Statamic\\Fields\\Field->rules()
#9 /var/www/html/vendor/statamic/cms/src/Fields/Field.php(275): Statamic\\Fields\\Field->isRequired()
#10 /var/www/html/vendor/statamic/importer/src/Http/Controllers/ImportController.php(35): Statamic\\Fields\\Fields->toPublishArray()

Environment

Environment
Application Name: SE Cluster Playbook
Laravel Version: 12.55.1
PHP Version: 8.4.18
Composer Version: 2.9.5
Environment: local
Debug Mode: ENABLED
Maintenance Mode: OFF
Timezone: UTC
Locale: en

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

Drivers
Broadcasting: log
Cache: file
Database: mysql
Logs: stack / single
Mail: log
Queue: redis
Session: file

Statamic
Addons: 5
Sites: 1
Stache Watcher: Enabled (auto)
Static Caching: Disabled
Version: 6.7.1 PRO

Statamic Addons
statamic/importer: 2.1.0
statamic/eloquent-driver: 5.4.2
statamic/seo-pro: 7.3.0
statamic-rad-pack/typesense: 3.1.0

Installation

Existing Laravel app

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions