Skip to content

Icon fieldtype throws FileNotFoundException and 500s the page when stored value no longer exists in the configured icon set #14669

@freshface

Description

@freshface

Bug description

Description

Statamic\Fieldtypes\Icon::augment() loads the SVG via IconSet::get(), which calls Filesystem::get() with no exists() check and no try/catch. If the stored value points to a file that doesn't exist in the configured set, the entire request crashes with Illuminate\Contracts\Filesystem\FileNotFoundException instead of degrading gracefully.

This is particularly painful after the v5 → v6 default-icon-set redesign: icons that shipped in v5 (e.g. swap, plus others) were removed in v6, so any entry that selected one of those icons now 500s on the front end with no migration path.

==

Actual

Illuminate\Contracts\Filesystem\FileNotFoundException
File does not exist at path .../vendor/statamic/cms/resources/svg/icons/swap.svg
  at vendor/statamic/cms/src/Icons/IconSet.php:43
  at vendor/statamic/cms/src/Fieldtypes/Icon.php:61
  at vendor/statamic/cms/src/Fields/Value.php:93
  at vendor/statamic/cms/src/Tags/Parameters.php:27
Entire page 500s.
IconSet::get(): ?string // check exists() first and return null when missing:
public function get(string $name): ?string
{
    $path = $this->directory.'/'.$name.'.svg';

    return $this->filesystem->exists($path)
        ? $this->filesystem->get($path)
        : null;
}

Icon::augment() already short-circuits on falsy values, so passing the null through is a no-op for callers. Net change: front-end stops crashing on orphaned content, behavior aligns with the svg tag.

Related concern

It would also be worth calling out the icon-set change in the v5 → v6 upgrade guide and/or providing a Stache/data-audit command that flags stored icon values no longer present in the configured set.

How to reproduce

Fresh Statamic 6 install.
Add an icon fieldtype to any blueprint.
In the database/file, set the stored value to a name that isn't present in vendor/statamic/cms/resources/svg/icons/ (e.g. swap, or simulate by deleting any svg from that dir after picking it).
Render the field on the front end with {{ svg :src="icon" }} (or anything that triggers augmentation via Value::value()).
Expected

Field returns null / empty string, page renders without the icon. Same fail-soft behavior as the svg tag's cascade (Svg.php:42), which already handles missing files gracefully.

Logs

Environment

Environment
Laravel Version: 13.8.0
PHP Version: 8.4.20
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: smtp
Queue: sync
Session: file

Storage
public/storage: NOT LINKED

Livewire
Livewire: v4.3.0

Statamic
Addons: 7
License Key: Not set
Sites: 1
Stache Watcher: Enabled
Static Caching: Disabled
Version: 6.18.1 PRO

Statamic Addons
aryehraber/statamic-captcha: 1.17.0
jacksleight/statamic-bard-texstyle: 4.1.0
marcorieser/statamic-livewire: 5.3.1
rias/statamic-address-field: 2.1.0
statamic-rad-pack/runway: 9.4.5
studio1902/statamic-peak-seo: 11.2.0
studio1902/statamic-peak-tools: 9.1.0

Installation

Fresh statamic/statamic site via CLI

Additional details

No response

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