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

  1. Delete the package directory and re-run 'composer install' to force a fresh Fossil clone.
  2. Verify the 'fossil' binary is installed and on PATH: 'which fossil'.
  3. Check that no build step or .gitignore rule is removing the .fslckout or _FOSSIL_ files.
  4. 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

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


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)