[5.x]: InvalidSubpathException when Default Upload Location uses an object template like {slug}
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 47
- Forks
- 32
- PR merge metrics
- No merged PRs in 30d
Description
Description
Opening an entry that has a CKEditor field crashes the Control Panel if the field’s Default Upload Location subpath uses an object template such as {slug}.
craft\errors\InvalidSubpathException: Could not resolve the subpath “{slug}”.
in craft/helpers/Assets.php (resolveSubpath)
from craft\ckeditor\Field::_defaultUploadFolderId()
The subpath is evaluated as an object template (same as Assets fields), but _defaultUploadFolderId() never receives the current element:
// Field.php (_inputHtml)
'defaultUploadFolderId' => $this->_defaultUploadFolderId(),
// Field.php (_defaultUploadFolderId)
[$subpath, $folder] = AssetsHelper::resolveSubpath($volume, trim($subpath ?? '', '/'));
Assets::resolveSubpath() is called with $element = null, so {slug} / {{ object.slug }} cannot resolve.
Assets fields handle this by:
- Passing the source element into subpath resolution
- Catching
InvalidSubpathExceptionand falling back to the user’s temp upload folder for new/draft entries
CKEditor does neither, so any dynamic subpath takes down the whole editor screen — even on already-saved entries that have a real slug.
_inputHtml() already has $element (it is passed to _linkOptions($element) on the next line).
Steps to reproduce
- Create a CKEditor field with Insert image in the toolbar.
- Under Assets, set Default Upload Location to a volume and subpath
{slug}. - Add the field to an entry type that has a slug (e.g. a channel section).
- Open an existing entry (or create a new one) that uses that field.
Expected: The editor loads. Drag-and-drop uploads go to a folder named after the entry slug (or the temp upload folder if the slug cannot be resolved yet).
Actual: The CP screen fails with InvalidSubpathException: Could not resolve the subpath “{slug}”.
A static subpath (e.g. posts) works. {slug} on a regular Assets field on the same entry also works.
Additional info
- Craft version: 5.10.13.2
- PHP version: 8.4.22
- Database driver & version: PostgreSQL 18.6
- Plugins & versions:
- CKEditor 5.7.0
- Bramble Search 1.5.0
- Child Me! 2.2.3
- Code Field 5.0.2
- Control Panel Nav 5.0.7
- Craft MCP v1.2.2
- Freeform 5.15.26
- Google Cloud Storage 2.2.2
- Metrix 2.0.5
- Navigation 3.0.22
- Neo 5.5.12
- Sentry Logger 5.0.3
- SEOmatic 5.1.22
- Sprout Redirects 5.0.9
- Workflow 3.0.16
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in Field.php at _inputHtml() and _defaultUploadFolderId(), then compare their subpath handling with Assets.php’s resolveSubpath() behavior. Verify the current element is available during input rendering and reproduce the {slug} case with a CKEditor field. Done means the editor loads, dynamic paths resolve for saved entries, and unresolved paths use the temporary upload folder.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100