ErrLookup › Background articles › RuntimeException: the generic unchecked failure libraries throw when the runtime breaks down
RuntimeException: the generic unchecked failure libraries throw when the runtime breaks down
RuntimeException is the unchecked exception that PHP and Java libraries reach for when an error surfaces during execution that is neither a programming bug nor a condition the caller signed up to handle. In the ErrLookup corpus it spans Symfony, Composer, Elasticsearch, Gson, and the ASP.NET Core SignalR Java client, and it appears in three roles: a fail-fast guard against an incompatible environment, a wrapper that adds context to a lower-level failure, and a hard stop when a resource or external dependency is unavailable. Developers meet it at autoload time, during console commands, inside build plugins, and while deserializing objects.
Distilled from 466 documented records across 8 repositories.
Background
RuntimeException sits at the top of the unchecked hierarchy in both PHP (the SPL class) and Java (java.lang.RuntimeException). Unlike checked exceptions in Java or LogicException in PHP, it signals a condition the caller could not reasonably have prevented through correct code alone: the runtime, the filesystem, the network, or the deployment environment failed the operation. Because the type is deliberately generic, the meaningful diagnostic information lives in the message and the chained cause rather than in the class itself, which is why two RuntimeExceptions from different libraries can describe entirely unrelated conditions.
Across the corpus the family takes three distinct shapes. First, a guard that fails fast: Composer's generated platform_check.php throws when the running PHP version or extensions violate the lockfile's constraints, Symfony's compression trait throws when neither the PHP extension nor the OS binary is present, and the Composer autoload generator embeds a PHP_VERSION_ID guard that aborts on PHP older than 5.6. Second, a wrapper that preserves a lower-level cause while adding the context the caller needs: Symfony's link tool wraps a JsonException and names the offending composer.json, Elasticsearch's Docker build task wraps an IOException from writing a marker file, and Gson wraps an Unsafe allocation or a constructor mismatch. Third, a hard stop when an external dependency is unavailable: Composer aborts when network is disabled and a git ref is not cached, and the GitHub driver aborts when API access fails and git fallback is turned off.
From the caller's side a RuntimeException is a terminal, non-recoverable signal. There is usually no partial state to continue from, and the fix lives outside the calling code, in the environment, the configuration, or a missing capability. The message is the primary diagnostic: many records embed the exact path, HTTP status code, JVM exit code, or archive status string that pinpoints the fault, and many chain a previous exception holding the root cause. Library conventions differ here, Composer and Symfony messages often name the remediation directly, while Elasticsearch and Gson messages lean on the caller to read the chained cause or an adjacent log file.
The family also reflects the conventions of the language ecosystem. In the PHP projects RuntimeException covers everything from archive creation to platform validation, and Composer marks several throws explicitly as \RuntimeException. In Java it spans build-time guards in Elasticsearch's Gradle plugins, TLS context initialization for the OTel log exporter, and the reflection-driven construction failures Gson hits during deserialization. The ASP.NET Core SignalR Java client uses it for protocol invariants such as an unrecognized message type or an empty handler callback list. Despite the shared name, none of these uses share a recovery strategy beyond the common thread of reading the message, following the chained cause, and fixing the external condition that tripped the guard.
Common causes
- Environment or platform mismatch.The deployment runtime differs from what the library or lockfile assumed. Composer's generated platform_check.php throws when PHP_VERSION_ID or loaded extensions violate the lockfile constraints, the Composer autoload guard aborts on PHP older than 5.6, and Symfony's compression trait throws when both the PHP extension and the OS binary are absent. The Elasticsearch reaper throws when its class is not found inside a JAR on the expected runtime classpath.
- Missing or contradictory configuration.A config value is absent, invalid, or self-contradictory. Composer throws when allow-plugins is unset in non-interactive mode, when a policy list gets a non-boolean value, or when a custom policy name collides with a reserved identifier. Symfony throws when an importmap entry declares both a path and a version, or when a routing parameter resolves to an env-var placeholder rather than a concrete scalar.
- External dependency or network resource unavailable.An operation needs a remote or external resource that cannot be reached. Composer aborts when COMPOSER_DISABLE_NETWORK is set and a git reference is not cached, the Symfony importmap version checker throws on a non-200 registry response, the Bitbucket driver throws on a Mercurial repository that Bitbucket no longer supports, and the GitHub driver throws when API access fails and git fallback is disabled.
- Wrapped filesystem or system-call failure.A lower-level IOException or syscall error is wrapped to add context. Elasticsearch's Docker build task wraps a failed marker-file write, Composer's ZipArchiver throws when ZipArchive open or close fails, the systemd notification module throws when socket creation is denied (often file-descriptor exhaustion), and the Fossil downloader throws when the checkout metadata file is missing.
- Malformed or unexpected input artifact.An input file or output stream does not match the shape the parser expects. Symfony's link tool throws on an unparseable composer.json, the insulated-request path throws when subprocess output lacks the serialized-object prefix, and Elasticsearch's OTel exporter throws on malformed or non-PEM certificate material.
- Reflection or object-construction failure.An object cannot be constructed during deserialization or service boot. Gson throws when Unsafe allocation fails for a class without a no-args constructor, and again when a custom TypeAdapter returns the wrong runtime type for a record component. Symfony wraps any failure to eagerly construct a non-lazy console command service.
- Build or protocol invariant violation.A compile-time or protocol contract is broken. Elasticsearch's scanner throws when a @NamedComponent lacks a matching @Extensible base, the SignalR Java client throws on an unrecognized message type or an empty handler callback list, and Symfony wraps any throw from a deprecated Bundle::registerCommands override.
What usually fixes it
- Inspect the chained previous exception and the message's embedded detail before changing anything. Many records wrap a lower-level cause whose message names the exact fault line, and the wrapper often carries a path, HTTP status, archive status string, or JVM exit code that localizes the problem.
- Verify the runtime environment satisfies the project's declared constraints. Match the PHP version and extensions to the lockfile, confirm the JVM or runtime can load required resources, and align dev, CI, and production runtimes so the generated guards do not trip after deploy.
- Confirm required extensions, binaries, and external services are reachable before the operation. Install the compression extension or OS binary, enable network or pre-warm the VCS cache, and validate registry and API connectivity, rather than letting the operation abort mid-flight.
- Prefer official generation tooling over hand-editing produced files. Use importmap:require instead of editing importmap.php, regenerate split composer.json files with upstream tooling, and regenerate the lock to set allow-plugins interactively, so validation guards never see a contradictory artifact.
- Check filesystem permissions, disk space, and process limits for write- and socket-heavy operations. Ensure the marker-file parent directory exists and is writable, confirm ext-zip is loaded and the target volume has space, and raise file-descriptor limits when socket creation is denied.
- Validate configuration and input artifacts before the operation that consumes them. Run composer validate on JSON, compare certificate and key moduli before deploying TLS material, and run debug:container on command dependencies before booting the console.
Go deeper
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Documented occurrences
- Error parsing "%s": %s(symfony/symfony)
- OUTPUT: %s ERROR OUTPUT: %s.(symfony/symfony)
- Could not determine the location of the composer.phar file as it appears you are not running this code from a phar archive.(composer/composer)
- The required git reference for '.$package->getName().' is not in cache and network is disabled, aborting(composer/composer)
- Eagerly loading command "%s" failed: declare its name at compile time with the #[AsCommand] attribute (or the "command" attribute of the "console.command" tag) so it can be loaded lazily.(symfony/symfony)
- Error %d finding metadata for package "%s". Response: %s(symfony/symfony)
- {preg_last_error_msg}(symfony/symfony)
- Composer detected issues in your platform: {issues}(composer/composer)
- Unable to locate {} on build classpath.(elastic/elasticsearch)
- %s compression is unsupported. Install the "%s" extension or run "composer require symfony/process" and install the "%s" command.(symfony/symfony)
- Failed to write marker file(elastic/elasticsearch)
- The .fslckout file is missing from {path}, see https://getcomposer.org/commit-deps for more information(composer/composer)
- ${url} does not appear to be a git repository, use ${cloneHttpsUrl} but remember that Bitbucket no longer supports the mercurial repositories. https://bitbucket.org/blog/sunsetting-mercurial-support-in-bitbucket(composer/composer)
- Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running {php_version}, please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.(composer/composer)
- Your composer.lock was generated before the allow-plugins security feature was introduced and your composer.json does not define allow-plugins. Run "composer update --lock" locally and commit the updated composer.lock, then add an explicit allow-plugins section to composer.json. See https://getcomposer.org/allow-plugins(composer/composer)
- Could not create archive '%s' from '%s': %s(composer/composer)
- "{value}" is an invalid value for {settingKey}, expected a boolean(composer/composer)
- Failed to initialise TLS context for OTel log export(elastic/elasticsearch)
- Named component {}({}) does not extend from an extensible class(elastic/elasticsearch)
- Unexpected message type: %d(dotnet/aspnetcore)
…and 446 more across the corpus — use search.
Honest provenance: generated on 2026-08-12 from AI-assisted analysis of the linked records. See how records are made.