symfony/translation · error · InvalidResourceException
$rb->getErrorMessage()
Error message
$rb->getErrorMessage()
What it means
IcuDatFileLoader::load() throws InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode()) when intl_is_failure() reports the ResourceBundle's error code is a failure. The message is the ICU/intl error text itself, so the thrown message equals whatever ICU reported (e.g. 'U_MISSING_RESOURCE_ERROR').
Solutions
- Log/inspect the ICU error code (the exception code) and map it: U_MISSING_RESOURCE_ERROR means the locale is absent from the bundle.
- Rebuild the bundle to include the requested locales.
- Fix filesystem access (permissions/open_basedir) if the code is U_FILE_ACCESS_ERROR.
- Align the PHP intl ICU version with the version used to compile the bundles.
Example fix
// before
$rb = new \ResourceBundle('es', '/app/resources/messages'); // bundle only contains en, fr
// after
$locales = ['en', 'fr'];
if (!in_array('es', $locales, true)) {
throw new \RuntimeException('Locale es missing from ICU bundle; rebuild with msgfmt.');
} Defensive patterns
Strategy: try-catch
Validate before calling
$rb = new \ResourceBundle($locale, $basePath);
if ($rb && intl_is_failure($rb->getErrorCode())) {
throw new \RuntimeException('ICU failure '.$rb->getErrorCode().': '.$rb->getErrorMessage());
} Type guard
function intlBundleHealthy(\ResourceBundle $rb): bool { return !intl_is_failure($rb->getErrorCode()); } Try / catch
try {
$catalogue = $loader->load($basePath, $locale);
} catch (Symfony\Component\Translation\Exception\InvalidResourceException $e) {
// $e->getCode() is the ICU error code (e.g. U_MISSING_RESOURCE_ERROR)
error_log('ICU error '.$e->getCode().': '.$e->getMessage());
} Prevention
- Map ICU error codes in monitoring (codes are the exception code).
- Include all required locales when building bundles.
- Fix permissions/open_basedir so ICU can read bundle data files.
- Keep PHP intl ICU data in sync with bundle compiler version.
When it happens
Trigger: ResourceBundle was created successfully but its internal error code is an ICU failure (e.g. U_MISSING_RESOURCE_ERROR, U_FILE_ACCESS_ERROR), detected via intl_is_failure($rb->getErrorCode()).
Common situations: Bundle file exists but the requested locale table is missing inside it, ICU data file access issues (permissions, open_basedir), or an ICU version mismatch producing warnings escalated to failures.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Cannot load resource
- $rb->getErrorMessage()
- Cannot parse message translation: please install the "intl"…
- This is not a local file
- File " " not found.
AI-assisted analysis of symfony/translation@ae9e8a51bc (2026-09-15).
Data as JSON: /api/errors/8b85137981b59375.
Report an issue: GitHub.
Appendix: source
Thrown at Loader/IcuDatFileLoader.php:45
{
if (!stream_is_local($resource.'.dat')) {
throw new InvalidResourceException(\sprintf('This is not a local file "%s".', $resource));
}
if (!file_exists($resource.'.dat')) {
throw new NotFoundResourceException(\sprintf('File "%s" not found.', $resource));
}
try {
$rb = new \ResourceBundle($locale, $resource);
} catch (\Exception) {
$rb = null;
}
if (!$rb) {
throw new InvalidResourceException(\sprintf('Cannot load resource "%s".', $resource));
} elseif (intl_is_failure($rb->getErrorCode())) {
throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
}
$messages = $this->flatten($rb);
$catalogue = new MessageCatalogue($locale);
$catalogue->add($messages, $domain);
if (class_exists(FileResource::class)) {
$catalogue->addResource(new FileResource($resource.'.dat'));
}
return $catalogue;
}
}
View on GitHub (pinned to ae9e8a51bc)