Jump to content

Larger files uploads are not compleating


Recommended Posts

Hello,

I'm encountering a bug, then using the File field type and attempt an a largish file 20mb upload the progress bar goes to 100%, but then the circular icon that spins just keeps spinning. This happened all of a sudden to all of our process wire sites simultaneously. Thinking it might be our host I tried doing a blank install with just the File field present and the same thing happens. 

I have tried the following:

  • Making sure the PHP.ini file is setup to accept larger files.
  • Changing the permission on the asset folder.
  • Checking the console and logs for error messages (they provided no error).

If some of you could try this (uploading a big file with the File field type, I'd be interested to know if I'm just really unlucky or is this a bug in the current build of Process Wire.

Also any help would be greatly appreciated.

Thanks,

Mark.

Link to comment
Share on other sites

@Mark_invisu Hey, sorry to hear you're having trouble.

I just uploaded a 30mb file to a ProcessWire install (latest version) and it worked as expected.

I think that your host may be a factor in this issue since you did have issues with all of your sites at the same time. Hosting companies can make trouble for anyone on any CMS unfortunately. Here are a few things you can try taking a look at.

POST upload size. You did mention setting up .ini to accept larger files, but it would be worth checking off your list if you can confirm that the post_max_size parameter is slightly larger than upload_max_filesize. So for accepting 64mb files, upload_max_filesize=64M and post_max_size=65M. I've missed this detail before.

HTTP response code. In your browser developer tools, switch over to the "Network" tab and then attempt to upload a file, then look at the return HTTP response code. Anything other than 200 indicates a problem.

Hosting server security. Hosting companies can be overzealous with their security settings. A specific example is ModSecurity which can cause web applications to choke either due to overly strict settings or false positives. Depending on whether the hosting company is using it and how it's configured, your HTTP response may help indicate an issue. A hosting company I've used updated their rules and suddenly some requests from ProcessWire failed with a HTTP 418 response on all sites I had on their server at the same time. Cute, but frustrating. If you see anything like that it could be a good indicator that this may be an issue. It's not a sure thing since security rules can be configured to return any HTTP code.

Server logs. If you can access them, check out log files outside of ProcessWire, specifically access_log and error_log. The error_log file may be useful since that is where you'll likely find log entries for server security hits. If you see something similar to this:

[Wed Apr 16 19:02:07.918136 2025] [authz_core:error] [pid 3599862:tid 128359658948288] [client X.X.X.X:XXXX] AH01630: client denied by server configuration: /some/path/on/your/server/here

then you're seeing something block the action you're trying to take when uploading. ModSecurity also logs to access_log and error_log if I remember correctly.

PHP logs. If you can access the logs for PHP itself it might be helpful. Entries in a log like php8.3-fpm.log usually contain errors/exceptions that the application/ProcessWire generally see and log themselves, but checking is a good idea to be thorough.

Digging into information outside of ProcessWire will probably be the most helpful. ProcessWire logs errors and exceptions pretty consistently so the fact that you aren't seeing any log entries generated in the PW admin makes me think that this is something failing outside of PHP execution and the result isn't visible to PHP itself. That may or may not be true, but looking at the items above would be the first places I start.

If you're coming up short after doing more research, you may need to hop on a chat with the hosting support team so they can take a look at anything that you may not have access to or control over.

  • Like 4
Link to comment
Share on other sites

Thank you for your comprehensive response,

Ajusting. the php.ini file had no affect. the network tab in developer tools returned on 200 errors. The log files you mentioned don't seem to be present so i've requested access to those, some other things i didn't mention in my original post are:

  • I've tried this on another host and get the same problem.
  • I can upload smaler files it's only he bigger ones it's having trouble with

Here is the response from the host for my recent query:

I've had a look at the error log that my colleague has referenced and below is the error that appears
  

2025-04-15 15:39:11	oracle	https://demo.invisu.uk/control/page/edit/	Fatal Error:  Uncaught TypeError: Exception::__construct(): Argument #2 ($code) must be of type int, string given in /data04/insiteportal/public_html/wire/core/FieldtypeMulti.php:254 Stack trace: #0 /data04/insiteportal/public_html/wire/core/FieldtypeMulti.php(254): Exception->__construct('SQLSTATE[HY000]...', 'HY000', Object(PDOException)) #1 /data04/insiteportal/public_html/wire/core/Wire.php(419): ProcessWire\FieldtypeMulti->___savePageField(Object(ProcessWire\RepeaterPage), Object(ProcessWire\Field)) #2 /data04/insiteportal/public_html/wire/core/WireHooks.php(968): ProcessWire\Wire->_callMethod('___savePageFiel...', Array) #3 /data04/insiteportal/public_html/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\FieldtypeFile), 'savePageField', Array) #4 /data04/insiteportal/public_html/wire/core/PagesEditor.php(918): ProcessWire\Wire->__call('savePageField', Array) #5 /data04/insiteportal/public_html/wire/core/Pages.php(868): ProcessWire\PagesEditor->saveField(Object(ProcessWire\RepeaterPage), Object(ProcessWire\Field), Array) #6 /data04/insiteportal/public_html/wire/core/Wire.php(422): ProcessWire\Pages->___saveField(Object(ProcessWire\RepeaterPage), 'installation_qu...', Array) #7 /data04/insiteportal/public_html/wire/core/WireHooks.php(968): ProcessWire\Wire->_callMethod('___saveField', Array) #8 /data04/insiteportal/public_html/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\Pages), 'saveField', Array) #9 /data04/insiteportal/public_html/wire/core/Page.php(2423): ProcessWire\Wire->__call('saveField', Array) #10 /data04/insiteportal/public_html/wire/modules/Process/ProcessPageEdit/ProcessPageEdit.module(2737): ProcessWire\Page->save('installation_qu...') #11 /data04/insiteportal/public_html/wire/core/Wire.php(416): ProcessWire\ProcessPageEdit->___ajaxSave(Object(ProcessWire\RepeaterPage)) #12 /data04/insiteportal/public_html/wire/core/WireHooks.php(968): ProcessWire\Wire->_callMethod('___ajaxSave', Array) #13 /data04/insiteportal/public_html/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\ProcessPageEdit), 'ajaxSave', Array) #14 /data04/insiteportal/public_html/wire/modules/Process/ProcessPageEdit/ProcessPageEdit.module(556): ProcessWire\Wire->__call('ajaxSave', Array) #15 /data04/insiteportal/public_html/wire/core/Wire.php(413): ProcessWire\ProcessPageEdit->___execute() #16 /data04/insiteportal/public_html/wire/core/WireHooks.php(968): ProcessWire\Wire->_callMethod('___execute', Array) #17 /data04/insiteportal/public_html/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\ProcessPageEdit), 'execute', Array) #18 /data04/insiteportal/public_html/wire/core/ProcessController.php(361): ProcessWire\Wire->__call('execute', Array) #19 /data04/insiteportal/public_html/wire/core/Wire.php(413): ProcessWire\ProcessController->___execute() #20 /data04/insiteportal/public_html/wire/core/WireHooks.php(968): ProcessWire\Wire->_callMethod('___execute', Array) #21 /data04/insiteportal/public_html/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\ProcessController), 'execute', Array) #22 /data04/insiteportal/public_html/wire/core/admin.php(174): ProcessWire\Wire->__call('execute', Array) #23 /data04/insiteportal/public_html/wire/modules/AdminTheme/AdminThemeUikit/controller.php(15): require('/data04/insitep...') #24 /data04/insiteportal/public_html/site/templates/admin.php(15): require('/data04/insitep...') #25 /data04/insiteportal/public_html/wire/core/TemplateFile.php(328): require('/data04/insitep...') #26 /data04/insiteportal/public_html/wire/core/Wire.php(413): ProcessWire\TemplateFile->___render() #27 /data04/insiteportal/public_html/wire/core/WireHooks.php(968): ProcessWire\Wire->_callMethod('___render', Array) #28 /data04/insiteportal/public_html/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\TemplateFile), 'render', Array) #29 /data04/insiteportal/public_html/wire/modules/PageRender.module(581): ProcessWire\Wire->__call('render', Array) #30 /data04/insiteportal/public_html/wire/core/Wire.php(416): ProcessWire\PageRender->___renderPage(Object(ProcessWire\HookEvent)) #31 /data04/insiteportal/public_html/wire/core/WireHooks.php(968): ProcessWire\Wire->_callMethod('___renderPage', Array) #32 /data04/insiteportal/public_html/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\PageRender), 'renderPage', Array) #33 /data04/insiteportal/public_html/wire/core/WireHooks.php(1094): ProcessWire\Wire->__call('renderPage', Array) #34 /data04/insiteportal/public_html/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\Page), 'render', Array) #35 /data04/insiteportal/public_html/wire/modules/Process/ProcessPageView.module(193): ProcessWire\Wire->__call('render', Array) #36 /data04/insiteportal/public_html/wire/modules/Process/ProcessPageView.module(114): ProcessWire\ProcessPageView->renderPage(Object(ProcessWire\Page), Object(ProcessWire\PagesRequest)) #37 /data04/insiteportal/public_html/wire/core/Wire.php(416): ProcessWire\ProcessPageView->___execute(true) #38 /data04/insiteportal/public_html/wire/core/WireHooks.php(968): ProcessWire\Wire->_callMethod('___execute', Array) #39 /data04/insiteportal/public_html/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\ProcessPageView), 'execute', Array) #40 /data04/insiteportal/public_html/index.php(55): ProcessWire\Wire->__call('execute', Array) #41 {main}   thrown (line 254 of /data04/insiteportal/public_html/wire/core/FieldtypeMulti.php)

The error here is referencing line 254 in the file FieldtypeMulti.php
This file can be found in public_html/wire/core. This directory is a core processwire code.
This is the line that is causing the error

            throw new WireDatabaseQueryException($e->getMessage(), $e->getCode(), $e);

In the error the code is asking for one thing and is getting a different value.
With this being a processwire file there isnt something I can really assist on amending.
You can try and get the CMS to generate a new config file as Im assuming the original files will be tailored for MySQL instead of MariaDB.

Looking at the file and error online, you can look at amending the code to change the second argument to an integer.
I highly recommend doing this with caution though as like I mentioned before this is a core processwire code so amending this may come with risks so please proceed with caution if you go down this route.

  • Thanks 1
Link to comment
Share on other sites

Interestingly, this seems to be a known issue for developers that extend PHP's base Exception class and potentially use and/or end up extending the PDOException class when dealing with database-related exceptions. This is likely to be the case here, and is a known oddity within PHP, and requires some sort of workaround. @ryan may want to take a look at the core Exception classes to determine how to handle the expected int value being returned as an alphanumeric (string) value.

That said, you should be safe to temporarily adjust the core file's code to forcibly typecast the return value to an integer in order to get past the above PHP error - which is only being shown because there's another error elsewhere that might give us more information towards solving your other problem. (FieldtypeMulti.php line 254)

throw new WireDatabaseQueryException($e->getMessage(), (int) $e->getCode(), $e);

If after adjusting the line above you still get an error with Exception code values not being an integer, you could adjust wire/core/Exceptions.php at line 40

$this->code = (int) $code;

That would catch any class extended from WireException and make sure the property has a proper integer value assigned.

NOTE: As your support's colleague mentions, modifying the core code is not recommended. For scenarios like this you can always change it temporarily so you can continue your debugging. Change it back once you're done so that you remain on-par with the official branch of the software.

  • Like 3
Link to comment
Share on other sites

That's very interesting @BrendonKoz and good to know for everyone who stumbles upon this issue. I've been writing software for many years and haven't run into this, but I've never caught/rethrown database level exceptions for a few reasons, now this one as well. The main concern I have about casting the error code to an int will erase the code entirely since it has alphabetical characters, and that information may be important to debugging. Example:

<?php

// An unreasonably friendly error
$error = 'hello1234';

echo (int) $error; // <= outputs 'int(0)'

@Mark_invisu To get a true fix for your sites, it would be a good idea to get a better look at what is happening deeper in your setup. If you modify the core code to handle strings by casting to ints, you'll have modified the core code to bypass an issue that is not relevant to your problem.

Take a look at L253 in /wire/core/FieldtypeMulti.php

<?php

try {
  // since we don't manage IDs of existing values for multi fields, we delete the existing data and insert all of it again
  $query = $database->prepare("DELETE FROM `$table` WHERE pages_id=:page_id"); // QA
  $query->bindValue(":page_id", $page_id, \PDO::PARAM_INT);
  $query->execute();
} catch(\Exception $e) {
  if($useTransaction) $database->rollBack();
  if($config->allowExceptions) throw $e; // throw original (L253 HERE)
  throw new WireDatabaseQueryException($e->getMessage(), $e->getCode(), $e);
}

What you really want to be troubleshooting is the database issue that is causing the exception to be thrown in the first place. The original exception will contain the information and further details you need.

My recommendation is to tell ProcessWire to throw the original Exception from PHP rather that catch/throw a WireException derived object. You're still going to get an exception, but it will contain all of the error details you need and doesn't require modifying the core.

<?php

// ... rest of /site/config.php

$config->allowExceptions = true;

I think this is the best way to fix your issue now, and then if/when the issue with the WireDatabaseQueryException is handled in the core, you can upgrade in the future where a patch may be implemented.

The good news is that exposing the base exception should give you all of the information you need without possibly needing to dig through additional logs. It is worth noting that the logs will likely be inaccurate because they'll be logging the ProcessWire variable type exception and not the database exception.

If you can share the stack trace that you should see when enabling exceptions it would be of interest to others that may be seeing this issue. I'm also personally curious even though I haven't run into this myself.

Edited by FireWire
I forgot to add a semicolon to my suggestion which would just cause another error.
  • Like 1
Link to comment
Share on other sites

2 hours ago, FireWire said:

That's very interesting @BrendonKoz and good to know for everyone who stumbles upon this issue. I've been writing software for many years and haven't run into this, but I've never caught/rethrown database level exceptions for a few reasons, now this one as well. The main concern I have about casting the error code to an int will erase the code entirely since it has alphabetical characters, and that information may be important to debugging.

I'd normally agree with the concern of losing the error code, but from what I could tell, I think the alphanumeric error code as reported by the database itself is retained in the errorMessage property anyway - at least for PDOException objects. I don't like to make assumptions though, which is why I figure Ryan would be the best person to determine how he might want to handle that in the end. 🙂

Quote

 My recommendation is to tell ProcessWire to throw the original Exception from PHP rather that catch/throw a WireException derived object. You're still going to get an exception, but it will contain all of the error details you need and doesn't require modifying the core.

<?php

// ... rest of /site/config.php

$config->allowExceptions = true;

I think this is the best way to fix your issue now, and then if/when the issue with the WireDatabaseQueryException is handled in the core, you can upgrade in the future where a patch may be implemented.

Nice! Yes, I like that solution (to get further in the error discovery) better than mine. 👍

  • Like 1
Link to comment
Share on other sites

1 minute ago, BrendonKoz said:

I'd normally agree with the concern of losing the error code, but from what I could tell, I think the alphanumeric error code as reported by the database itself is retained in the errorMessage property anyway - at least for PDOException objects

I'm pretty sure you're right about that. That's a good catch of my try (I'll show myself out) 🚪🏃‍♂️

2 minutes ago, BrendonKoz said:

I like that solution (to get further in the error discovery)

Embrace the fatal error, and if the situation demands it- ask for another 😆

  • Haha 1
Link to comment
Share on other sites

@Mark_invisu - due to your report, I created an issue report in ProcessWire's Issues github repository for Ryan to see. He's made core changes to related files in an effort to rectify that, but since he's not experiencing the error, was looking to see if the changes he's made alleviates the fatal error you are seeing (with relation to the Exceptions).

If you're able to test this and report back, that would be awesome.

Thanks!!

Link to comment
Share on other sites

Hello Adrian,

Thanks for putting so much effort into resolving this, i incorporated the code changed into a fresh install of the dev version of process wire but the problem still persists. Just to recap, we can upload files up to 8mb but anothing over that we just get an endless spinning graphic. We have tried this on multiple hosts, but we get the same behaviour. Is there anything else that can be done, as we hve multiple sites all dependant on process wire and the ability to upload large files (around 50mb)

Many thanks,

Mark

Link to comment
Share on other sites

@Mark_invisu I mentioned above in my comment attempting to get to the underlying exception that may reveal the error that is occurring would be the most helpful in this situation.

Are you able to make this change to your config file and attempt an upload again? It would be helpful to see the exception being thrown during the database transaction.

On 4/17/2025 at 9:22 AM, FireWire said:
<?php

// ... rest of /site/config.php

$config->allowExceptions = true;

Seeing the original error would be very helpful to understanding what is causing your issue beyond the type error exception that is being thrown by ProcessWire.

If you're able to get to the error using this config property you may very well be able to skip any upgrades to ProcessWire or modifications to the core. Please share the resulting exception message you are receiving if you can do this. Without this information and the difficulty of others replicating your issue, it is very difficult to provide any advice or help.

Link to comment
Share on other sites

Posted (edited)

Hello Fire,

I can see you've put a lot of effort in helping to solve this so thanks for that, here is all the data from Firefox debugger:

Headers Response:

HTTP/2 504
server: nginx
date: Wed, 23 Apr 2025 14:56:32 GMT
content-type: text/html
content-length: 160
X-Firefox-Spdy: h2

Request Headers

POST /control/page/edit/?id=1&InputfieldFileAjax=1 HTTP/2
Host: poeshappyplace.co.uk
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:137.0) Gecko/20100101 Firefox/137.0
Accept: */*
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate, br, zstd
X-FILENAME: Untitled-2.png
X-FIELDNAME: upload
Content-Type: application/octet-stream
X-TOKEN1027973821X1745402814: siSF1CH8q.0WZrbaHLdq0L0z.LhNvGRm
X-REQUESTED-WITH: XMLHttpRequest
Content-Length: 17481650
Origin: https://poeshappyplace.co.uk
Connection: keep-alive
Referer: https://poeshappyplace.co.uk/control/page/edit/?id=1
Cookie: pagelist_open=JSON%5B%221-0%22%5D; wires_challenge=Fe1sdoBFEE6xRXKvRdBmNztesp%2FtkiDf; wires=659c1ebb45dd2830f72c4db8969fc57f; cpsession=%3aoH5Knnk_sYcRqUrk%2c8bdec0a2f45dd7304be705768bc383a6; timezone=Europe/London
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
TE: trailers

Stack Trace

(Async: EventListener.handleEvent) jQuery.ready.promise https://poeshappyplace.co.uk/wire/modules/Jquery/JqueryCore/JqueryCore.js:1:48608
 
Seems like it's timing out after the download at which point i assume it's doing the database interaction, it doesn't write an error to any of the logs, it just times out. One host has confirmed that they are recoeving a ReceiveAckHdr: timeout 300 is exceeded error in their logs, their ReceiveAckHdr is set to 5 minutes which i would have thought would be more than enough, i can confirm this as in developer tools i can see that:
 
 
sits there for about five minutes before returning a 501 timeout error, i hope this helps and if you require any further information to debug this, thank you for helping me with this.
 
 
 
 
Thanks,
 
Mark.
Edited by Mark_invisu
Link to comment
Share on other sites

The $config->allowExceptions value won't manifest in the browser dev tools where that information you posted came from

On 4/17/2025 at 6:38 AM, Mark_invisu said:

I've had a look at the error log that my colleague has referenced and below is the error that appears

If you can set the $config->allowExceptions to true and then find out how to get the new stack trace where your colleague was able to see it that would be the information you need.

  • Like 1
Link to comment
Share on other sites

Hello FireWire,

I set allowExceptions to true the developer tools after the timeout returns the following error:

JQMIGRATE: Migrate is installed, version 1.4.1
InputfieldFile.min.js?v=129-3.0.246:1 
            
            
           POST https://poeshappyplace.co.uk/control/page/edit/?id=1&InputfieldFileAjax=1 504 (Gateway Timeout)
uploadFile @ InputfieldFile.min.js?v=129-3.0.246:1
traverseFiles @ InputfieldFile.min.js?v=129-3.0.246:1
(anonymous) @ InputfieldFile.min.js?v=129-3.0.246:1Understand this error
VM220:1 Uncaught SyntaxError: Unexpected token '<', "<html>
<h"... is not valid JSON
    at JSON.parse (<anonymous>)
    at XMLHttpRequest.<anonymous> (InputfieldFile.min.js?v=129-3.0.246:1:6460)
(anonymous) @ InputfieldFile.min.js?v=129-3.0.246:1
XMLHttpRequest.send
uploadFile @ InputfieldFile.min.js?v=129-3.0.246:1
traverseFiles @ InputfieldFile.min.js?v=129-3.0.246:1
(anonymous) @ InputfieldFile.min.js?v=129-3.0.246:1Understand this error

Thanks,

Mark

Link to comment
Share on other sites

Hello, 

This issue still hasn't been resolved however I have learned some new information. After upload the script runs for exactly five minutes and then returns a 504 Timeout error, which seems odd to me that this shouldn't take so long I suspect its the http request timeout setting in the apache configuration. I cannot find any error's in any of the logs to provide information, if anybody has any ideas what could be causing this I would be very grateful.

Many thanks

Mark

Link to comment
Share on other sites

Do you know where your host's support was originally able to get the server and/or PHP error logs that originally showed the issue with the core ProcessWire file's exception? You mention no errors are showing up in the logs, but the logs from the ProcessWire admin/backend may not be able to store the error message if it's happening at a lower level in the stack. The browser dev tools can be helpful to some degree, but it's not the only place to look, nor is the PW admin. If you're not seeing any useful error logs in those two places, have you looked (or been able to look?) at the server logs, whether those are NGINX/Apache, or PHP (runtime) logs?

It seems you may be getting different responses depending on the host you're on (you mentioned both a 501 and 504 timeout errors), so having any sort of definitive logs to look at, if they exist somewhere, would be awesome.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...