What happened?
Description
Assets\UploadController::upload throws a TypeError whenever an asset
field is configured with a dynamic subpath (e.g. {uid}) and a user
uploads a file directly from the entry editor.
TypeError: CraftCms\Cms\Element\Elements::getElementById():
Argument #1 ($elementId) must be of type int, string given
The dynamic-subpath case is the one that takes the getElementById($elementId, ...)
branch in UploadController::upload — Craft needs the element to resolve
the {uid} (or {slug}, etc.) template variable into a real folder. Form-
encoded request data is always strings on the PHP side, but
Elements::getElementById() declares strict int $elementId, so PHP 8's
strict types throw before the resolve can run.
Static-subpath fields don't hit this codepath: when the upload location
resolves to a fixed folder, folderId is already populated and the
elementId branch is skipped.
The two neighbouring calls in the same method (folderId, fieldId)
already use $request->integer(...), so this looks like a missed-spot
consistency bug rather than an intentional design choice.
Steps to reproduce
- Spin up a fresh Craft 6.0.0-alpha.4 install on PHP 8.5 (strict types).
- Create a Channel section ("Hub Resources" in my repro) with an Assets
field ("Cover Image" in my repro).
- In the field's settings, under Default Upload Location:
- Volume: pick any volume (in my repro: "Hub Resource Assets",
an R2-backed volume — same behaviour on local volumes)
- Subpath:
{uid} (any template variable will do; the bug fires on
any non-empty subpath that needs element context to resolve)
- Save the field, open an entry that uses it, and click Upload files
on the field. Choose any file.
The browser posts to admin/actions/assets/upload with form data:
fieldId: 8
elementId: 18
siteId: 1
_token: …
assets-upload: (binary)
The request 500s instead of completing the upload.
Expected behavior
The upload completes and the asset is created in the resolved folder.
Actual behavior
TypeError in
Elements::getElementById()
because $elementId arrives as "18" (string) rather than 18 (int).
Stack trace:
TypeError: CraftCms\Cms\Element\Elements::getElementById():
Argument #1 ($elementId) must be of type int, string given,
called in /var/www/html/vendor/craftcms/cms/src/Http/Controllers/Assets/UploadController.php on line 68
Craft CMS version
6.0.0-alpha.4
PHP version
PHP 8.5.5
Operating system and version
macOS 26.3 (host) Debian GNU/Linux 13 (trixie) (DDEV web container)
Database type and version
psql (PostgreSQL) 17.10 (Debian 17.10-1.pgdg13+1)
Image driver and version
Imagick — ImageMagick 7.1.1-43 Q16 aarch64 22550 https://imagemagick.org
Installed plugins and versions
What happened?
Description
Assets\UploadController::uploadthrows aTypeErrorwhenever an assetfield is configured with a dynamic subpath (e.g.
{uid}) and a useruploads a file directly from the entry editor.
The dynamic-subpath case is the one that takes the
getElementById($elementId, ...)branch in
UploadController::upload— Craft needs the element to resolvethe
{uid}(or{slug}, etc.) template variable into a real folder. Form-encoded request data is always strings on the PHP side, but
Elements::getElementById()declares strictint $elementId, so PHP 8'sstrict types throw before the resolve can run.
Static-subpath fields don't hit this codepath: when the upload location
resolves to a fixed folder,
folderIdis already populated and theelementIdbranch is skipped.The two neighbouring calls in the same method (
folderId,fieldId)already use
$request->integer(...), so this looks like a missed-spotconsistency bug rather than an intentional design choice.
Steps to reproduce
field ("Cover Image" in my repro).
an R2-backed volume — same behaviour on local volumes)
{uid}(any template variable will do; the bug fires onany non-empty subpath that needs element context to resolve)
on the field. Choose any file.
The browser posts to
admin/actions/assets/uploadwith form data:The request 500s instead of completing the upload.
Expected behavior
The upload completes and the asset is created in the resolved folder.
Actual behavior
TypeErrorinElements::getElementById()because
$elementIdarrives as"18"(string) rather than18(int).Stack trace:
Craft CMS version
6.0.0-alpha.4
PHP version
PHP 8.5.5
Operating system and version
macOS 26.3 (host) Debian GNU/Linux 13 (trixie) (DDEV web container)
Database type and version
psql (PostgreSQL) 17.10 (Debian 17.10-1.pgdg13+1)
Image driver and version
Imagick — ImageMagick 7.1.1-43 Q16 aarch64 22550 https://imagemagick.org
Installed plugins and versions