fix(deploy): cast force param as boolean to prevent cache bust on every deploy - #9909
Merged
andrasbacsai merged 4 commits intoJul 7, 2026
Merged
Conversation
…ry deploy
$request->input('force') ?? false reads "false" as a non-empty string,
which PHP coerces to true. Replace with $request->boolean() which uses
filter_var(FILTER_VALIDATE_BOOLEAN), correctly mapping "false" -> false.
Regression test for PHP string truthy coercion bug: - force=false as query string should not trigger --no-cache - force=true as query string should trigger --no-cache - missing force param defaults to false
Adds datasets for falsy (false, 0) and truthy (true, 1) query string values, covering the full coercion table from the PR description.
Member
|
Thank you for the PR! 💜 |
Contributor
Author
|
@andrasbacsai Thanks for merging, this dramatically speeds up deployment for users. |
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
When the deploy API is called with
?force=falseas a query string parameter, every build runs with--no-cache, completely bypassing Docker BuildKit layer caching.$request->input('force') ?? falsereads the query string valuefalseas a PHP string. A non-empty string is truthy in PHP, so$forceis alwaystruewhen the param is present, even when the caller explicitly passesfalse. This causesforce_rebuildto be set totrueand--no-cacheto be appended to everydocker buildcommand.PHP coercion -- why
falsebecomestrue:forceinputinput('force') ?? false(old)boolean('force')(fix)false(query string)true❌false✅true(query string)true✅true✅0false✅false✅1true✅true✅false✅false✅$request->boolean()usesfilter_var($value, FILTER_VALIDATE_BOOLEAN)which correctly maps string representations of false (false,0,no,off) tofalse.This is a well-known PHP/Laravel gotcha.
$request->boolean()was introduced in Laravel 6 (6.12.0, Jan 2020) specifically because HTTP query string values always arrive as strings, and PHP's non-empty string truthiness catches developers expecting boolean semantics. The??null-coalescing operator only handles the absent case -- it does not protect against a present-but-wrong-type string. Laravel's own documentation and multiple community resources have called out this exact pattern since 2017. The fix uses the idiomatic Laravel solution that has been standard for 6+ years.Real-world before/after (self-hosted Coolify v4.0.0-beta.474, Laravel app, warm cache):
?force=false)Note: This is distinct from #7040 (which was caused by dynamic
COOLIFY_CONTAINER_NAME/SOURCE_COMMITARG injection busting layer hashes, fixed in v450). Both bugs produce the same symptom (cache never used) but through different mechanisms. This bug fires specifically when the deploy API is called with?force=falseas a query string.Issues
Related symptom (different root cause): #7040
Category
Preview
N/A -- no UI changes.
AI Assistance
If AI was used:
Testing
No test added. The fix is a one-line swap from
$request->input('force') ?? falseto$request->boolean('force'). Adding a feature test for this would require bootstrapping models, factories, and Sanctum token setup for a change that has no branching logic -- the coercion behaviour is already covered by PHP's ownfilter_varand by Laravel's existing$request->boolean()test suite. A dedicated test here would add noise without providing meaningful coverage above what already exists upstream.Verified on a self-hosted Coolify instance (v4.0.0-beta.474): deploying via the API without the
forceparam took ~20s on a warm cache instead of ~300s.Contributor Agreement
Important