Sometimes a harmless-looking view include can explode with a deep PHP error. Here’s the one I hit on PHP 8.3:
TypeError array_replace_recursive(): Argument #2 must be of type array, int given resources/views/partials/xyz.blade.php:100 require In my case it was triggered while resolving a translation string via __('site.translation'). The root cause? A corrupted (actually deleted) translation file: resources/lang/en/site.php. Restoring that file from backup fixed everything instantly.
Why Laravel Ends Up Calling array_replace_recursive()
Laravel’s translation subsystem merges arrays from multiple sources (files, vendor packages, fallbacks). These merges rely on those files returning arrays. If any loaded source returns a non-array (like an int, string, or null), the internal merge throws the type error shown above.
Quick TL;DR
- Symptom:
array_replace_recursive()complains about a non-array argument. - Likely cause: A translation or config file doesn’t return an array (missing/corrupted/accidentally edited).
- Fix: Restore/repair the file so it returns an array, then clear caches.
The Specific Case: Missing Translation File
I had calls like:
{{ __('site.translation') }} But the file resources/lang/en/site.php had been deleted. A valid translation file must look like:
<?php return [ 'translation' => 'Your text here', 'welcome' => 'Welcome to our site!', ]; After restoring that file from backup, the error disappeared.
Other Common Causes (and Fixes)
1) Translation file returns a scalar or nothing
Broken:
<?php return 123; // not an array Correct:
<?php return [ 'key' => 'value', ]; 2) Misconfigured config files in config/*.php
Laravel merges config arrays too. If a config file returns a string/int, you can see the same error during bootstrap.
Broken:
<?php return 'database'; // Correct:
<?php return [ 'default' => 'mysql', 'connections' => [ // ... ], ]; 3) Cached config/translations are stale
Even if files look fine, stale cache can preserve a previously broken state. Clear caches:
php artisan config:clear php artisan cache:clear php artisan view:clear php artisan route:clear 4) Merging user input or env values into arrays
If custom code calls array_replace_recursive() with values derived from request or env without type checks, a scalar can slip in. Validate and cast before merging:
<?php
function safe_array_merge(array $base, $maybeArray): array
{
if (!is_array($maybeArray)) {
// log and coerce to empty array to avoid hard errors
logger()->warning('Expected array in merge; got '.gettype($maybeArray));
$maybeArray = [];
}
return array_replace_recursive($base, $maybeArray);
}
5) Malformed vendor/override structure
When publishing vendor translations or configs, partial overrides that return non-arrays can break merges. Verify published files under resources/lang/vendor and config/ return arrays.
6) Encoding/BOM or syntax errors that short-circuit returns
A stray byte order mark, syntax error, or early exit can prevent the array from being returned, leaving null. Run a lint pass:
find resources/lang -name "*.php" -print0 | xargs -0 -n1 php -l find config -name "*.php" -print0 | xargs -0 -n1 php -l Debugging Checklist
- Read the stack and file hint: The error showed in
resources/views/partials/xyz.blade.php:100; check what’s being translated/merged on that line. - Verify translation keys: Quick probe in a tinker session:
php artisan tinker >>> Lang::get('site'); // expect an array for a group file - Open the group file: Ensure
resources/lang/en/site.phpexists and returns an array. - Search for non-array returns: Grep for suspicious returns:
rg --hidden "return\s+[^[]|return\s+null" resources/lang config - Clear caches: Run the Artisan clears shown above.
- Re-test: Reload the page or rerun the failing code path.
Preventive Tips
- Version control
resources/langandconfig. Enable branch protections and CI checks. - Static checks in CI: Lint all PHP config/lang files and assert they return arrays.
- Guard rails in custom code: If you manually merge arrays, validate types first (as shown in
safe_array_merge()). - Backups: Keep periodic backups so accidental deletions are easy to undo.
Conclusion
The error array_replace_recursive(): Argument #2 must be of type array, int given typically means a translation or config file doesn’t return an array. In the scenario above, a deleted resources/lang/en/site.php file caused __('site.translation') to blow up. Restoring the file and clearing caches resolved it immediately. If you see the same message, audit your translation/config files first—then cache, merges, and any custom code that combines arrays.
Last Updated on 20 August 2025
