symfony/symfony · error · IOException
Symbolic link "%s" was created but appears to be broken.
Error message
Symbolic link "%s" was created but appears to be broken.
What it means
Thrown by assets:install's symlink() helper after it successfully calls $filesystem->symlink($originDir, $targetDir) but file_exists($targetDir) still returns false. This indicates the symlink was created but resolves to a non-existent or inaccessible target — a 'broken symlink' — so the command refuses to report success.
Source
Thrown at src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php:231
}
return $method;
}
/**
* Creates symbolic link.
*
* @throws IOException if link cannot be created
*/
private function symlink(string $originDir, string $targetDir, bool $relative = false): void
{
if ($relative) {
$this->filesystem->mkdir(\dirname($targetDir));
$originDir = $this->filesystem->makePathRelative($originDir, realpath(\dirname($targetDir)));
}
$this->filesystem->symlink($originDir, $targetDir);
if (!file_exists($targetDir)) {
throw new IOException(\sprintf('Symbolic link "%s" was created but appears to be broken.', $targetDir), 0, null, $targetDir);
}
}
/**
* Copies origin to target.
*/
private function hardCopy(string $originDir, string $targetDir): string
{
$this->filesystem->mkdir($targetDir, 0o777);
// We use a custom iterator to ignore VCS files
$this->filesystem->mirror($originDir, $targetDir, Finder::create()->ignoreDotFiles(false)->in($originDir));
return self::METHOD_COPY;
}
private function getPublicDirectory(ContainerInterface $container): string
{
$defaultPublicDir = 'public';View on GitHub (pinned to 698e28026c)
Solutions
- Verify the bundle's origin assets directory exists at <BundlePath>/Resources/public or <BundlePath>/public.
- On Windows, run the terminal as Administrator or enable Developer Mode for symlink support, or use copy mode (omit --symlink).
- On NFS/volume mounts, prefer copy mode: `assets:install public` (no --symlink).
- Re-run after fixing the origin dir; remove the broken symlink manually if needed.
Example fix
# before php bin/console assets:install public --symlink # -> 'Symbolic link ... appears to be broken' # after (fall back to copy) php bin/console assets:install public # or fix the missing origin: ensure <Bundle>/Resources/public exists
Defensive patterns
Strategy: validation
Validate before calling
// Verify the bundle origin exists before symlinking
foreach ($kernel->getBundles() as $bundle) {
$origin = is_dir($bundle->getPath().'/Resources/public')
? $bundle->getPath().'/Resources/public'
: $bundle->getPath().'/public';
if (!is_dir($origin)) { /* skip or warn */ }
} Prevention
- On Windows, enable Developer Mode or run as admin for symlink support, or use copy mode.
- On NFS/volume mounts, omit --symlink and use copy.
- Ensure each bundle's public/ assets dir exists before installing.
When it happens
Trigger: Running `assets:install --symlink` when the bundle's Resources/public (or public) origin directory was removed after the symlink target computation, the origin path is on a filesystem that doesn't report through file_exists (some Windows/NFS setups), or the symlink target became stale mid-operation.
Common situations: Bundles whose assets directory doesn't exist at the computed origin path. NFS/Vagrant/Docker volume mounts where symlink resolution is unreliable. Windows without symlink privileges (though that usually fails at symlink() not here). Origin dir deleted/renamed after glob.
Related errors
- The target directory "%s" does not exist.
- File or directory "%s" is not readable.
- Error parsing "%s": %s
- Unable to write in the "%s" directory.
- Error parsing JSON from asset manifest file "%s": {json_erro
AI-assisted analysis of symfony/symfony@698e28026c (2026-08-06).
Data as JSON: /api/errors/3f1643a61572978e.
Report an issue: GitHub.