tl;dr: I think the isWindows thing in Yii's Mutex library/feature/whatever(?) is broken. I'm getting an error because it seems to be trying to do the Unix method of deleting a file, but I'm on Windows.
I was trying out the Project Config feature, but saw that every time I'd change a field name or the like, the form submission (from whatever change I had just made) would result in an error ("Invalid Server Config", perhaps?). I'd have to access the CP at another URL to trigger the prompt to update the project.yaml file, after which it would allow me to access the CP.
I can't imagine this is the correct workflow with Project Config, but it's what I was getting, so... 🤷♂️
After battling with this "workflow" for a while, I gave up and decided to selectively and temporarily enable Project Config each time just before I was ready to commit & push changes to the (remote) dev server. I disabled the option in general.php, refreshed the CP, and deleted the existing project.yaml.
Things seemed fine, but I noticed that the task queue was stuck on "Deleting stale template caches". There were about 6-8 of those tasks in the queue—no biggie. When I looked in the logs, I saw some sort of permission denied error relating to unlinking a /storage/runtime/mutex/[long hash here].lock file.
I continued to work on the fields and entries, and at some point I went to save an entry and encountered this error:
yii\base\ErrorException: unlink(C:\Projects\[project_name]/storage/runtime/mutex\d32bdcd122ec9ecabcbc581f1f69c6ea.lock): Permission denied in C:\Projects\[project_name]\vendor\yiisoft\yii2\mutex\FileMutex.php:161
Stack trace:
#0 C:\Projects\[project_name]\vendor\craftcms\cms\src\web\ErrorHandler.php(76): yii\base\ErrorHandler->handleError(2, 'unlink(C:\\Projects ...', 'C:\\Projects\\[project_name]...', 161)
#1 [internal function]: craft\web\ErrorHandler->handleError(2, 'unlink(C:\\Projects ...', 'C:\\Projects\\[project_name]...', 161, Array)
#2 C:\Projects\[project_name]\vendor\yiisoft\yii2\mutex\FileMutex.php(161): unlink('C:\\Projects\\[project_name]...')
#3 C:\Projects\[project_name]\vendor\yiisoft\yii2\mutex\Mutex.php(88): yii\mutex\FileMutex->releaseLock('structure:203')
#4 C:\Projects\[project_name]\vendor\craftcms\cms\src\services\Structures.php(467): yii\mutex\Mutex->release('structure:203')
#5 C:\Projects\[project_name]\vendor\craftcms\cms\src\services\Structures.php(281): craft\services\Structures->_doIt(203, Object(benf\neo\elements\Block), Object(craft\records\StructureElement), 'appendTo', 'insert')
#6 C:\Projects\[project_name]\vendor\spicyweb\craft-neo\src\services\Blocks.php(351): craft\services\Structures->appendToRoot(203, Object(benf\neo\elements\Block))
#7 C:\Projects\[project_name]\vendor\spicyweb\craft-neo\src\services\Fields.php(298): benf\neo\services\Blocks->buildStructure(Array, Object(benf\neo\models\BlockStructure))
#8 C:\Projects\[project_name]\vendor\spicyweb\craft-neo\src\Field.php(571): benf\neo\services\Fields->saveValue(Object(benf\neo\Field), Object(craft\elements\Entry), false)
#9 C:\Projects\[project_name]\vendor\craftcms\cms\src\base\Element.php(1882): benf\neo\Field->afterElementSave(Object(craft\elements\Entry), false)
#10 C:\Projects\[project_name]\vendor\craftcms\cms\src\elements\Entry.php(1105): craft\base\Element->afterSave(false)
#11 C:\Projects\[project_name]\vendor\craftcms\cms\src\services\Elements.php(515): craft\elements\Entry->afterSave(false)
#12 C:\Projects\[project_name]\vendor\craftcms\cms\src\controllers\EntriesController.php(549): craft\services\Elements->saveElement(Object(craft\elements\Entry))
#13 [internal function]: craft\controllers\EntriesController->actionSaveEntry()
#14 C:\Projects\[project_name]\vendor\yiisoft\yii2\base\InlineAction.php(57): call_user_func_array(Array, Array)
#15 C:\Projects\[project_name]\vendor\yiisoft\yii2\base\Controller.php(157): yii\base\InlineAction->runWithParams(Array)
#16 C:\Projects\[project_name]\vendor\craftcms\cms\src\web\Controller.php(109): yii\base\Controller->runAction('save-entry', Array)
#17 C:\Projects\[project_name]\vendor\yiisoft\yii2\base\Module.php(528): craft\web\Controller->runAction('save-entry', Array)
#18 C:\Projects\[project_name]\vendor\craftcms\cms\src\web\Application.php(297): yii\base\Module->runAction('entries/save-en...', Array)
#19 C:\Projects\[project_name]\vendor\craftcms\cms\src\web\Application.php(561): craft\web\Application->runAction('entries/save-en...', Array)
#20 C:\Projects\[project_name]\vendor\craftcms\cms\src\web\Application.php(281): craft\web\Application->_processActionRequest(Object(craft\web\Request))
#21 C:\Projects\[project_name]\vendor\yiisoft\yii2\base\Application.php(386): craft\web\Application->handleRequest(Object(craft\web\Request))
#22 C:\Projects\[project_name]\web\index.php(21): yii\base\Application->run()
#23 {main}
The bit that caught my attention though is this, from the error page (note the line comment I added to signify which line was highlighted as the line where the error originated):
>
PHP Warning – yii\base\ErrorException
unlink(C:\Projects[project_name]/storage/runtime/mutex\d32bdcd122ec9ecabcbc581f1f69c6ea.lock): Permission denied
if ($this->isWindows) {
// Under windows it's not possible to delete a file opened via fopen (either by own or other process).
// That's why we must first unlock and close the handle and then *try* to delete the lock file.
flock($this->_files[$name], LOCK_UN);
fclose($this->_files[$name]);
@unlink($this->getLockFilePath($name));
} else {
// Under unix it's possible to delete a file opened via fopen (either by own or other process).
// That's why we must unlink (the currently locked) lock file first and then unlock and close the handle.
unlink($this->getLockFilePath($name)); // THIS LINE IS HIGHLIGHTED
flock($this->_files[$name], LOCK_UN);
fclose($this->_files[$name]);
}
unset($this->_files[$name]);
return true;
}
Now I can go to the base CP URL and it will load, but the queue is growing larger and larger, and I also see a couple of pending "Resaving {section_name} entries" tasks there as well. I have a feeling that continuing like this will corrupt something entirely.
composer.json—I checked and these are accurate to what the CP shows: "vlucas/phpdotenv": "^2.4.0",
"spicyweb/craft-neo": "2.2.4",
"supercool/buttonbox": "2.0.2",
"craftcms/redactor": "2.3.1",
"verbb/field-manager": "2.0.5",
"verbb/super-table": "2.1.9",
"misterbk/mix": "1.5.2",
"alexmarchant/advanced-image-field": "1.0.0",
"aelvan/imager": "v2.1.4",
"craftcms/contact-form": "2.2.3",
"craftcms/contact-form-honeypot": "1.0.2"
Can you create a simple PHP file alongside your web/index.php file with this?
<?php
echo DIRECTORY_SEPARATOR;
When you access the script with your browser, what does it output?
Nevermind, this is a Craft bug.
Most helpful comment
Nevermind, this is a Craft bug.