composer/composer · error · RuntimeException
The .fslckout file is missing from
Error message
The .fslckout file is missing from {path}, see https://getcomposer.org/commit-deps for more information What it means
Thrown by FossilDownloader::doUpdate() when the target package directory does not contain a Fossil SCM checkout. The code at FossilDownloader.php:63-64 calls hasMetadataRepository($path), which checks for the presence of $path/.fslckout or $path/_FOSSIL_ (line 126). If neither file exists, a RuntimeException is thrown. This means Composer expected a Fossil-managed working directory but found none, indicating the package was not installed via Fossil clone.
Solutions
- Delete the package directory and re-run 'composer install' to force a fresh Fossil clone.
- Verify the 'fossil' binary is installed and on PATH: 'which fossil'.
- Check that no build step or .gitignore rule is removing the .fslckout or _FOSSIL_ files.
- Ensure the package's source type in composer.json or the remote repository is correctly set to 'fossil'.
Example fix
# before $ composer update vendor/fossil-pkg # RuntimeException: The .fslckout file is missing from ... # after: force reinstall $ rm -rf vendor/vendor/fossil-pkg $ composer install
Defensive patterns
Strategy: validation
Validate before calling
// Verify Fossil metadata before update
$path = 'vendor/' . $package->getName();
if (!is_file($path . '/.fslckout') && !is_file($path . '/_FOSSIL_')) {
// Re-clone by removing the directory
\Composer\Util\Filesystem::removeDirectory($path);
} Type guard
function hasFossilMetadata(string $path): bool {
return is_file($path . '/.fslckout') || is_file($path . '/_FOSSIL_');
} Try / catch
try {
$downloader->update($initial, $target, $path, $url);
} catch (\RuntimeException $e) {
if (str_contains($e->getMessage(), '.fslckout file is missing')) {
// Remove the path and re-install to get a fresh checkout
\Composer\Util\Filesystem::removeDirectory($path);
$downloader->install($target, $path, $url);
}
throw $e;
} Prevention
- Ensure no build step or .gitignore rule removes .fslckout or _FOSSIL_ files.
- Verify the 'fossil' binary is installed and on PATH.
- Delete and re-clone the package directory if metadata is corrupted.
When it happens
Trigger: Updating a package whose source type is 'fossil' but whose install directory lacks Fossil metadata files. This happens when the directory was created by a different downloader, manually emptied, or the checkout was partially deleted.
Common situations: A dependency using type:fossil where the checkout was corrupted or the .fslckout file was deleted (e.g. by .gitignore cleanup or a build process that strips dotfiles). Switching source types. Filesystem cleanup tools removing metadata files.
Related errors
- Can not clone to access package information. The " "…
- Failed to execute
- Failed to open repository
- Could not completely delete
- Could not remove
AI-assisted analysis of composer/composer@c435d285c9 (2026-08-07).
Data as JSON: /api/errors/5c25835cc1437dc2.
Report an issue: GitHub.
Appendix: source
Thrown at src/Composer/Downloader/FossilDownloader.php:64
$this->execute(['fossil', 'clone', '--', $url, $repoFile]);
$this->execute(['fossil', 'open', '--nested', '--', $repoFile], $realPath);
$this->execute(['fossil', 'update', '--', (string) $package->getSourceReference()], $realPath);
return \React\Promise\resolve(null);
}
/**
* @inheritDoc
*/
protected function doUpdate(PackageInterface $initial, PackageInterface $target, string $path, string $url): PromiseInterface
{
// Ensure we are allowed to use this URL by config
$this->config->prohibitUrlByConfig($url, $this->io);
$this->io->writeError(" Updating to ".$target->getSourceReference());
if (!$this->hasMetadataRepository($path)) {
throw new RuntimeException('The .fslckout file is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');
}
$realPath = Platform::realpath($path);
$this->execute(['fossil', 'pull'], $realPath);
$this->execute(['fossil', 'up', '--', (string) $target->getSourceReference()], $realPath);
return \React\Promise\resolve(null);
}
/**
* @inheritDoc
*/
public function getLocalChanges(PackageInterface $package, string $path): ?string
{
if (!$this->hasMetadataRepository($path)) {
return null;
}
View on GitHub (pinned to c435d285c9)