Troubleshooting Icon Discovery
When to Use
Icons aren't appearing, pack definitions aren't loading, or icon IDs aren't resolving correctly.
Decision
| Symptom | Likely cause | Debug method |
|---|---|---|
| Pack not listed | YAML syntax error, or a top-level $schema: key |
Check YAML validity, remove $schema, rebuild cache |
Pack listed but icons is empty |
Remote source on svg/svg_sprite, or a disallowed local extension (.webp, .woff2) |
Check dblog for "Invalid icon path extension" / "No icon found in source" |
| Icons not found | Source pattern does not match, or discovery is not recursive | Verify the pattern, remember Finder::depth(0) |
| Wrong icon renders | Icon ID collision across sources in the same pack | Later source wins; check every sources: entry |
| Nothing renders, no error | icon() given an unknown pack/icon, or #pack/#icon instead of #pack_id/#icon_id |
getIconRenderable() returns [] for empty IDs |
ArgumentCountError / TypeError on icon |
icon('pack:id') or icon('pack:id', {…}) |
Use three arguments |
IconPackConfigErrorException at cache rebuild |
Bad pack ID, missing extractor/template, missing config: sources |
Read the exception message; it names the provider and pack |
Changes to *.icons.yml not taking effect |
Nothing watches the file | drush cr after every edit |
Pattern
Debug icon pack definitions:
# List all icon packs
drush php:eval "print_r(array_keys(\\Drupal::service('plugin.manager.icon_pack')->getDefinitions()));"
# Get specific pack definition
drush php:eval "print_r(\\Drupal::service('plugin.manager.icon_pack')->getDefinition('my_theme'));"
# Check if pack has icons
drush php:eval "print_r(\\Drupal::service('plugin.manager.icon_pack')->getIcons(['my_theme']));"
Validate YAML files. yaml_parse_file() is a PECL extension function and is usually absent; use Drupal's own serializer:
# Check YAML syntax with the serializer Drupal actually uses
drush php:eval "print_r(\\Drupal\\Component\\Serialization\\Yaml::decode(file_get_contents('themes/my_theme/my_theme.icons.yml')));"
# Or use yamllint
yamllint themes/my_theme/my_theme.icons.yml
Full schema validation only runs when justinrainbow/json-schema is installed (IconPackManager::setValidator()). Without it, a malformed definition passes discovery and fails later at render time instead:
composer require --dev justinrainbow/json-schema
drush cr # definitions are now validated against icon_pack.schema.json
Debug icon file paths:
# Verify icon files exist
ls -la themes/my_theme/icons/
# Check if pattern matches files
# Pattern: icons/{icon_id}.svg
# File: icons/home.svg
# Should match: icon('my_theme', 'home')
Enable Twig debugging:
# sites/default/services.yml
parameters:
twig.config:
debug: true
auto_reload: true
cache: false
Add debug output to template:
{# Temporary debug output #}
{{ dump({
icon_id: icon_id,
source: source,
content: content|length ~ ' chars',
settings: _context
}) }}
<svg>{{ content }}</svg>
Check extractor discovery:
// In custom module or theme preprocess
function my_module_preprocess_page(&$variables) {
$icon_manager = \Drupal::service('plugin.manager.icon_pack');
$pack = $icon_manager->getDefinition('my_theme');
\Drupal::logger('debug')->debug('<pre>@pack</pre>', [
'@pack' => print_r($pack, TRUE),
]);
}
Reference: /core/lib/Drupal/Core/Theme/Icon/Plugin/IconPackManager.php
Common Mistakes
- Not clearing cache after YAML changes → Run
drush crafter every*.icons.ymlmodification; nothing invalidates on file change - Adding
$schema:to*.icons.yml→ Breaks discovery for the whole site - Case-sensitive icon IDs →
home≠Home; IDs come straight from filenames with no normalisation - Assuming validation ran → Without
justinrainbow/json-schema,validateDefinition()returns TRUE unconditionally - Missing file extensions in patterns → Pattern
icons/{icon_id}matches{svg,png,gif}; a wrong explicit extension matches nothing - Debugging in production → Enable Twig debug only in development, impacts performance