Page MenuHomePhabricator

VisualEditor in 1.35 not working (404 / Permanent Loading)
Open, Needs TriagePublicBUG REPORT

Description

I'm writing this report in the assumption that Visual Editor is supposed to work 'out-of-the-box' which it doesn't for me - i actually didn't get it to work at all yet.
Coming from here https://www.mediawiki.org/wiki/Topic:Vunt92vkiyisn8cu others seem to have the same issues.

I'm maintaining a small Wiki-Family with a global wiki only for images in the root folder (hidden to users, they don't get there without knowing direct links) and localized wikis in subfolders (/de, /en, etc.).
This done with a basic symlink setup as described on the respective Wiki-Family mediawiki page and works fine.

Out-of-the-box with that setup the Visual Editor errors out with 'Error contacting the Parsoid/RESTBase server (HTTP 404)' on all localized wikis in subfolders but in the global wiki in the root.

Configuring manually the following URLs for each family wiki will remove that error.
$wgVisualEditorRestbaseURL = "https://example.com/en/api/rest_v1/page/html/";
$wgVisualEditorFullRestbaseURL = "https://example.com/en/api/rest_";
(Replacing /en with the respective subfolder, of course)

Unfortunately the Visual Editor is nontheless not working on any of the wikis, neither the global one in the root nor the family wikis. When attempting to edit a page i do see the Wiki Editor, but the actual content of the page is gone and the loading icon is persistent as in the picture below that should technically show a lot of headlines and text, as the page is full of it.

To make sure this is not caused by family setup i've installed a new mediawiki on a dedicated subdomain separate from all other wikis and it shows the same picture like above (while not showing the 404).

I'm possibly just too dumb to use, but given it's supposed to work out-of-the-box i thought to report this as noone else in the mentioned thread has done it yet.

Related Objects

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

@D3nnis3n: Calls to rest.php need to be parsed by the PHP parser. Please make sure, in your server configuration, that such calls go through the PHP parser.

It's a default configuration, there is no reason for it not to. All other PHP files are correctly executed.

If you are referring to

Also note that in the default nginx configuration, the PHP files are recognised as location ~ \.php$ but this should be changed to location ~ \.php($|/) or a more specific expression which will recognise /possible/prefix/rest.php/other/arguments/of/rest. The endpoint rest.php is the first of MediaWiki which really needs a "pretty URL" (i.e. "arguments" after the file.php). There were already "pretty URLs for index.php but this was an advanced optional configuration.

This cannot be done on webhosting.

More debugging info:

  • in VirtualRESTServiceClient, my request looks like
'method' => 'GET',
    'url' => '/restbase/local/v1/page/html/Testapresechec/6534?redirect=false&stash=true',
    'query' => 
    array (
    ),
    'headers' => 
    array (
      'Accept' => 'text/html; charset=utf-8; profile="https://www.mediawiki.org/wiki/Specs/HTML/2.0.0"',
      'Accept-Language' => 'en',
      'User-Agent' => 'VisualEditor-MediaWiki/1.35.0',
      'Api-User-Agent' => 'VisualEditor-MediaWiki/1.35.0',
    )

It then gets translated into the variable executeReq

array (
    'method' => 'GET',
    'url' => 'http://10.21.37.104/rest.php/10.21.37.104/v3/page/html/Testapresechec/6534?redirect=false&stash=true',
    'query' => 
    array (
    ),
    'headers' => 
    array (
      'Accept' => 'text/html; charset=utf-8; profile="https://www.mediawiki.org/wiki/Specs/HTML/2.0.0"',
      'Accept-Language' => 'en',
      'User-Agent' => 'VisualEditor-MediaWiki/1.35.0',
      'Api-User-Agent' => 'VisualEditor-MediaWiki/1.35.0',
      'Cookie' => 'new_wiki_135UserName=Grossmb; wikiEditor-0-toolbar-section=%5Bobject%20Object%5D; wikiEditor-0-booklet-characters-page=%5Bobject%20Object%5D; wikiEditor-0-booklet-help-page=%5Bobject%20Object%5D; new_wiki_135_session=360fhmmdsb107j4kj63ov904c4bgcjqh; new_wiki_135UserID=15; VEE=wikitext',
      'Host' => '10.21.37.104',
    ),
    'chain' => 
    array (
    ),
    'reqTimeout' => 360,
  )

Note the switch from v1 to v3 in the URL.

The request is then passed to the REST router, which then tries to match the URL in the request with the rest core routes (includes/Rest/coreRoutes.json). Now, on my installation, this file does not include any v3 paths. So it is not surprising it cannot find a match in the service matchers and it returns 404.
There are other issue related to the matching: the URL above includes the IP of my server in the relative path ($relpath) and this seems to also cause the route matching to fail.

I am able to get valid results (i.e.200) by manipulating the URL and using the URLs below:

http://10.21.37.104/rest.php/v1/page/Testapresechec/history
http://10.21.37.104/rest.php/v1/page/Testapresechec/bare

Hopefully, this will help the VE team get a better idea of where the issue originates from.

OK so it looks like I was able to fix my issue by simply commenting out the cookie forwarding option in my LocalSettings

$wgVirtualRestConfig['modules']['parsoid']['forwardCookies'] = true;

(which I needed when using the external parsoid service because I was using Windows authentication). I suspect setting this variable switched the class from

ParsoidVirtualRESTService::class

to

RestbaseVirtualRESTService::class

in function getVRSObject() : VirtualRESTService in ApiParsoidTrait.php. I now see the Parsoid routes are loaded in the Rest router

[05-Oct-2020 08:29:23 Canada/Eastern] routeFiles=array (
  0 => 'E:\\Websites\\mediawiki-1.35.0/includes/Rest/coreRoutes.json',
  1 => 'E:\\Websites\\mediawiki-1.35.0/extensions\\VisualEditor\\includes\\VEParsoid\\parsoidRoutes.json',
)

and I am now able to edit existing pages and create new pages.

It looks like a number of separate issues are being mixed together in this task now. Some of them apparently are due to folks following outdated instructions in [[Parsoid/PHP]] instead of the @updated docs on the main [[Parsoid]] page. @ti_infotrad seems like they managed to address their issues. @Ciencia_Al_Poder was discussing differences between the configuration when RESTBase is used and when it is not.

The original bug by @D3nnis3n seem to be addressed by this fix to the nginx docs: https://www.mediawiki.org/w/index.php?title=Parsoid/PHP&type=revision&diff=3738829&oldid=3733379&diffmode=source which was moved to the main Parsoid wiki page in this revision.

As such I think this bug can be closed.

@cscott

I'm not sure if the solutions work for everyone. I tried both of @ssastry's suggested solutions and neither one worked for me. The .htaccess solution gives me a 403 error instead of 404.

@cscott
That does not fix my issue. I'm using that in my configuration.
It errors out with 404: https://example.com/rest.php/example.com/v3/page/html/Main%20Page
https://example.com/rest.php/example.com/v3/page/html/Main_Page

(Which is different than downloading a rest.api file, but still not working)

{"messageTranslations":{"en":"The requested relative path () did not match any known handler"},"httpCode":404,"httpReason":"Not Found"}

And yes, i did set:

$wgVirtualRestConfig['modules']['parsoid'] = [
    'url' =>  'https://example.com/rest.php',
    'domain' => 'example.com',
];

And yes, tested with a non-family installation.

Leading to

Error contacting the Parsoid/RESTBase server (HTTP 404)

when trying to use VE. Which is worse than before where at least that error wasn't there, but the content wasn't loaded.

And for notes:
VE works for creating a page that does not yet exist, but not for editing one that does already exist. (Like basically what i reported from the beginning, also in the topic)

E.g.
New Page: No 404
Editing a existing Page: 404

Excluding Visual Editor from my pretty url rewrites does not change this either.

Maybe also important due to the different issues mixed here:
I'm not using a manually installed Parsoid / RESTBase and i never had one installed before either. This is a normal wiki family upgraded to 1.35 trying to use the out-of-the-box VE, without any custom installation like others have or have had here.

@CostasAthan I was dealing with a 403 error as well, this is how I fixed it:

I'm using a semi-private wiki - everyone can read, but only registered users can write. If I changed permissions so everyone could also write, VE/Parsoid worked for me, so I did some digging and found this: https://www.mediawiki.org/wiki/User:Andrujhon/Allow_Parsoid_Server

However, this requires some modification. Apparently, VE/Parsoid now also requires the writeapi permission. After putting this at the end of my LocalSettings.php, Parsoid worked for me.

if ( !isset( $_SERVER['REMOTE_ADDR'] ) OR $_SERVER['REMOTE_ADDR'] == 'yourIpAddressHere' ) {
	$wgGroupPermissions['*']['read'] = true;
	$wgGroupPermissions['*']['edit'] = true;
	$wgGroupPermissions['*']['writeapi'] = true;
}

Keep in mind that I had to put my IPv6 address there, though that probably depends on your server and network configuration. I'm using shared webhosting, so I just used the address that showed up in the logs. Using the IPv4 address or 127.0.0.1 would not work for me.

//Edit: Fixed a missing ' in code

@TheConen

I also have set my wiki to what you mention as semi-private mode. That's probably not a coincidence.

Anyway I tested the code you suggested and the 403 error persists. I'm on shared hosting and as an IP I used the origin server's IP, Cloudflare's IPS and 127.0.0.1. None of them made a difference.

Have you installed Parsoid as an external server or do you use the implementation that comes with MediaWiki 1.35?

Okay, i finally got it to work:

location rest.php/ {
try_files $uri $uri/ /rest.php?$query_string;
}
location /de/rest.php/ {
try_files $uri $uri/ /de/rest.php?$query_string;
}
location /en/rest.php/ {
try_files $uri $uri/ /en/rest.php?$query_string;
}
location /ru/rest.php/ {
try_files $uri $uri/ /ru/rest.php?$query_string;
}

This makes VE work on all wikis if _NO_ additional configuration in the LocalSettings.php is made, e.g. not setting $wgVirtualRestConfig['modules']['parsoid'] or the Rest URLs.
Also important: No slash before the rest.php in the first case for the root wiki - it won't work with a slash!

@D3nnis3n

As I'm not familiar with Nginx, do you have an idea what the equivalent code for an .htaccess file would be?

@CostasAthan I'm using the bundled 1.35 version. I used the IP that showed up in the logs of my hosting provider and that worked for me, but it had to be the IPv6 address (which is the one that showed up in the logs) - the IPv4 would not work.

@CostasAthan Have you tried giving edit and writeapi permissions to * in general to see if that works?

@TheConen

No, I haven't. What I'm going to look at first though is what is the equivalent of @D3nnis3n solution for Nginx for an .htaccess file for Apache.

For the record, I found the following piece of code in extensions/VisualEditor/includes/VisualEditorHooks.php

// For the 1.35 LTS, Parsoid is loaded from includes/VEParsoid to provide a
                // "zero configuration" VisualEditor experience. In Wikimedia production, we
                // have $wgVisualEditorParsoidAutoConfig off (and $wgVirtualRestConfig set to
                // point to a separate cluster which has the Parsoid extension installed), so
                // this code won't be executed.
                if (
                        $wgVisualEditorParsoidAutoConfig
                        && !ExtensionRegistry::getInstance()->isLoaded( 'Parsoid' )
                        // Generally manually configuring VRS means that you're running
                        // Parsoid on a different host.  If you need to manually configure
                        // VRS, load the Parsoid extension explicitly.
                        && !isset( $wgVirtualRestConfig['modules']['parsoid'] )
                        && !isset( $wgVirtualRestConfig['modules']['restbase'] )
                ) {
                        // Only install these route files if we're auto-configuring and
                        // the parsoid extension isn't loaded, otherwise we'll conflict.
                        $wgRestAPIAdditionalRouteFiles[] = wfRelativePath(
                                __DIR__ . '/VEParsoid/parsoidRoutes.json', $IP
                        );
                }

I think this explains why the Parsoid routes were not loaded when I had

$wgVirtualRestConfig['modules']['parsoid']['forwardCookies'] = true;

in LocalSettings.php

@D3nnis3n

As I'm not familiar with Nginx, do you have an idea what the equivalent code for an .htaccess file would be?

No. If i was expert enough in this i'd probably have never needed to open this bug report.
But the documentation is still wrong, as it doesn't work with the slash at the beginning, it needs to be omitted in case you are not referencing a folder first.

Well, it's not completely working. On a long page with a lot of modules it fails to connect with an error 500, but on normal sized ones it seems to work fine.

mw.Api error:  apierror-visualeditor-docserver-http 
{error: {…}}
error:
code: "apierror-visualeditor-docserver-http"
docref: "See https://example.com/en/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> for notice of API deprecations and breaking changes."
info: "Error contacting the Parsoid/RESTBase server (HTTP 500)"
__proto__: Object
__proto__: Object

Error contacting the Parsoid/RESTBase server (HTTP 500)

Is there any limitations for VE? The page i observe this is probably 80 Din A4 Pages long and consists mostly of LUA-Modules grabbing data and forming it into tables.

//EDIT:
It actually seems like this is the only page i can get this error to happen. Would a link to the page help?

But yeh, i can live with a single page not working in Visual Editor (actually two, as pages that are formatted with bootstrap html via BootstrapComponents extension aren't displayed correctly either).
So technically my issue is solved. If there is a fix for my 500 i'd like to know about that of course and i'm sure the others with issues in here would also like to get their visual editor going - it's awesome when it works!
But i could open a new report for the 500, given it's very likely a totally different issue. I'm not sure how that works here, so please advise on the correct steps.

Well, it's not completely working. On a long page with a lot of modules it fails to connect with an error 500, but on normal sized ones it seems to work fine.
...
//EDIT:
It actually seems like this is the only page i can get this error to happen. Would a link to the page help?

Yes, please. But, since it is a HTTP 500, if you have access to the logs and you can send us a stack trace from the logs, that would be even more helpful!

I think this explains why the Parsoid routes were not loaded when I had

$wgVirtualRestConfig['modules']['parsoid']['forwardCookies'] = true;

in LocalSettings.php

Yes, I've updated the VisualEditor docs to more clearly state that setting any property in $wgVirtualRestConfig opts you out of Parsoid auto-configuration.

Well, it's not completely working. On a long page with a lot of modules it fails to connect with an error 500, but on normal sized ones it seems to work fine.
...
//EDIT:
It actually seems like this is the only page i can get this error to happen. Would a link to the page help?

Yes, please. But, since it is a HTTP 500, if you have access to the logs and you can send us a stack trace from the logs, that would be even more helpful!

https://wiki.play.eco/en/Crafting - This is the affected page.
I cannot find any errors in the apache logs for the domain. Do i need to activate anything in Mediawiki to have it write logs?

Check https://www.mediawiki.org/wiki/Manual:How_to_debug#Logging .. I looked at that page, and my guess is that maybe Parsoid timed out on that page.

@D3nnis3n For what it is worth, in 1.33, I had to modify the timeout in resources/src/mediawiki.api/index.js to fix a timeout for a page with lots of media links (https://www.mediawiki.org/wiki/Topic:Uqam69xv019t4r3m). Not sure if it applies to 1.35 or to your configuration.

That seems to not be the case, as the 500 does come after only 2 - 3 seconds, not 30. For testing i changed the value to 300 seconds and it brought no change.
I'll try adding the debug log and see if i can find anything.

Okay, found the solution:
128 MB memory limit for PHP is not enough for that page, setting it to 256 MB fixed the issue, Visual Editor took about 15 seconds to load, though. So a higher default timeout might be useful in rare circumstances where it could take that long.

I guess there is no way to make Visual Editor learn HTML / BootstrapComponents? We use that on the main page and visual editing looks weirdly wrong-formatted there.

AFAICT, looks like all concerns have been addressed and docs updated. Assuming there are no new concerns, I'll resolve this ticket later this week. Thanks everyone!

I guess there is no way to make Visual Editor learn HTML / BootstrapComponents? We use that on the main page and visual editing looks weirdly wrong-formatted there.

@Esanders ^ In any case, this is unrelated to the main topic of this ticket, and so if required, feel free to spawn it off in a new ticket.

AFAICT, looks like all concerns have been addressed and docs updated. Assuming there are no new concerns, I'll resolve this ticket later this week. Thanks everyone!

Hi @ssastry . Sorry, but I'm finding it difficult to spot the solution above. Would you be able to highlight again please? Is it shared on MediaWiki? As mentioned in my only previous comment, my private wiki too does not work out of the box.

Based on this solution that worked for @D3nnis3n, I modified my .htaccess file, which also implements short URLs, like this:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ %{DOCUMENT_ROOT}/index.php
RewriteRule rest.php/ /rest.php?%{QUERY_STRING} [L]

Now I get "Error contacting the Parsoid/RESTBase server (HTTP 403)", the same as with this code: https://www.mediawiki.org/w/index.php?title=Topic:Vv35plp6g16qno0s&topic_showPostId=vv4jia2ip0swopod#flow-post-vv4jia2ip0swopod

Should I consider both .htaccess solutions valid for the 404 error and start troubleshooting the 403? (My wiki allows editing only to registered users. I've seen others reporting the same error for VisualEditor for wikis with this setting, so maybe I should start another bug report for it.)

"Error contacting the Parsoid/RESTBase server (HTTP 403)"

This can be caused by two things: The server might disallow access to the file or MediaWiki returns the error 403. Check the URLs, which MediaWiki is trying to load in the developer tools of your browser. You can then call the URL to rest.php manually to verify what is going on:

  • If your server does not allow you to access the rest.php file, you are seeing an error message by the server. You are not seeing JSON content, which comes from MediaWiki. Make sure that the server allows accessing the file!
  • If the server does allow you to access rest.php, but you are seeing the error 403 in some kind of JSON format, the error 403 is caused by MediaWiki. In this case, make sure the MediaWiki write API is enabled.

@Joergi123

Here is the log of the server:

162.158.156.190 - - [08/Oct/2020:15:18:06 -0400] "GET /Main_Page HTTP/1.1" 200 8475 "https://[domain]/Main_Page?action=edit&veswitched=1" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 OPR/71.0.3770.228 (Edition avira-2)"

162.158.156.190 - - [08/Oct/2020:15:18:09 -0400] "GET /load.php?lang=en&modules=oojs-ui-core%2Coojs-ui-widgets&skin=timeless&version=7khli HTTP/1.1" 304 433 "https://[domain]/Main_Page?veaction=edit" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 OPR/71.0.3770.228 (Edition avira-2)"

162.158.156.190 - - [08/Oct/2020:15:18:09 -0400] "GET /load.php?lang=en&modules=ext.visualEditor.core&skin=timeless&version=1sypu HTTP/1.1" 304 433 "https://[domain]/Main_Page?veaction=edit" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 OPR/71.0.3770.228 (Edition avira-2)"

162.158.73.250 - - [08/Oct/2020:15:18:11 -0400] "GET /rest.php/[domain]/v3/page/html/Main_Page/95?redirect=false&stash=true HTTP/1.1" 403 455 "-" "VisualEditor-MediaWiki/1.35.0"

162.158.156.190 - - [08/Oct/2020:15:18:09 -0400] "GET /api.php?action=visualeditor&format=json&paction=parse&page=Main_Page&uselang=en&formatversion=2 HTTP/1.1" 200 931 "https://[domain]/Main_Page?veaction=edit" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 OPR/71.0.3770.228 (Edition avira-2)"

162.158.156.190 - - [08/Oct/2020:15:18:11 -0400] "POST /api.php HTTP/1.1" 200 885 "https://[domain]/Main_Page?veaction=edit" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 OPR/71.0.3770.228 (Edition avira-2)"

The error appears in the 4th entry.

By the way, I have started a relative task: T265043

GET /rest.php/[domain]/v3/page/html/Main_Page/95?redirect=false&stash=true HTTP/1.1" 403

The server does not allow access to rest.php. You need to change the server configuration so that rest.php can be called. Same as for api.php - according to your logs, api.php is working. rest.php is not.

When you visit the site (/rest.php/[domain]/v3/page/html/Main_Page/95?redirect=false&stash=true) with your browser, do you get a JSON that tells you "rest-write-denied" or do you get a 403 error message served by your webserver?

Make sure you are not logged in when visiting the site with your browser, use incognito mode.

When you visit the site (/rest.php/[domain]/v3/page/html/Main_Page/95?redirect=false&stash=true) with your browser, do you get a JSON that tells you "rest-write-denied" or do you get a 403 error message served by your webserver?

It's the first:

{"error":"rest-write-denied","httpCode":403,"httpReason":"Forbidden"}

By the way, do other codes like the 455 that appears next to the 403 have any special meaning?

In that case, you either need to apply the solution I described in T263928#6518831 or - if you are using HTTP only and no HTTPS - enable cookie forwarding as per https://www.mediawiki.org/wiki/Extension:VisualEditor#Forwarding_cookies_to_Parsoid. Keep in mind that if you enable cookie forwarding, you also have to manually configure Parsoid (https://www.mediawiki.org/wiki/Parsoid#Linking_a_developer_checkout_of_Parsoid).

In that case, you either need to apply the solution I described in T263928#6518831 or - if you are using HTTP only and no HTTPS - enable cookie forwarding as per https://www.mediawiki.org/wiki/Extension:VisualEditor#Forwarding_cookies_to_Parsoid. Keep in mind that if you enable cookie forwarding, you also have to manually configure Parsoid (https://www.mediawiki.org/wiki/Parsoid#Linking_a_developer_checkout_of_Parsoid).

I had already tried enabling cookie forwarding. That again results in a 404 error, probably because I use HTTPS.

I also have tried the solution you have mentioned using 127.0.0.1 and also the origin server's and Cloudflare's IPv4 IPs. No luck either. I will contact my hosting provider asking which IP I should use.

Try enabling edit and writeapi for everyone (*) for test purposes. If VisualEditor works then, you just have to find the right IP address to put in there. Have you tried IPv4 as well as IPv6?

Judging by the log you provided above, the IP address you need to use should be 162.158.73.250.

Also, i just noticed that there was a ' missing in the code snippet I provided earlier, so if you just copy-pasted that, it might not have worked for you. Try this:

if ( !isset( $_SERVER['REMOTE_ADDR'] ) OR $_SERVER['REMOTE_ADDR'] == '162.158.73.250' ) {
	$wgGroupPermissions['*']['read'] = true;
	$wgGroupPermissions['*']['edit'] = true;
	$wgGroupPermissions['*']['writeapi'] = true;
}

Judging by the log you provided above, the IP address you need to use should be 162.158.73.250.

That's a Cloudflare IP, just one of the many. It's not standard.

I modified the code like this:

if ( !isset( $_SERVER['REMOTE_ADDR'] ) OR in_array ($_SERVER['REMOTE_ADDR'], $cloudflareIPS ) ) {
	$wgGroupPermissions['*']['read'] = true;
	$wgGroupPermissions['*']['edit'] = true;
	$wgGroupPermissions['*']['writeapi'] = true;
}

having both v4 and v6 IPs in the array. Finally, I used an array with only v6 IPs. Again, no luck in both tries.

I will enable the things you mentioned globally and I will see what happens.

Oh well, you wouldn't want to enable access from all Cloudflare IPs... that's a big security risk. Anyone using any Cloudflare IP could edit your wiki. On the other hand, if all requests to your wiki go through Cloudflare, you cannot use this solution with an IP address. Using Cloudflare might actually be what stops you from using that solution in this case.

I honestly don't understand why VisualEditor/Parsoid doesn't use an internal mechanism that is independent of permission settings now that Parsoid is directly integrated into MediaWiki.

I honestly don't understand why VisualEditor/Parsoid doesn't use an internal mechanism that is independent of permission settings now that Parsoid is directly integrated into MediaWiki.

Mostly because the integration work is proceeding in stages and this is how far we could get done before the 1.35 LTS release became due. Another 3-6 months and the story might have been different.

I guess there is no way to make Visual Editor learn HTML / BootstrapComponents? We use that on the main page and visual editing looks weirdly wrong-formatted there.

@Esanders ^ In any case, this is unrelated to the main topic of this ticket, and so if required, feel free to spawn it off in a new ticket.

@D3nnis3n feel free to file tasks about VE support for these extensions. As they are not used on WMF wikis I suspect our team won’t be able to prioritise them, but you may get some response from the extension authors/maintainers.

Here is the log of the server:

162.158.156.190 - - [08/Oct/2020:15:18:06 -0400] "GET /Main_Page HTTP/1.1" 200 8475 "https://[domain]/Main_Page?action=edit&veswitched=1" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 OPR/71.0.3770.228 (Edition avira-2)"
[...]
162.158.73.250 - - [08/Oct/2020:15:18:11 -0400] "GET /rest.php/[domain]/v3/page/html/Main_Page/95?redirect=false&stash=true HTTP/1.1" 403 455 "-" "VisualEditor-MediaWiki/1.35.0"

Thought I'd just verify that the [domain] part above was you manually censoring the logs? If you're getting the literal text [domain] in your URLs then something is misconfigured (probably $wgServer)....

@cscott

No, I did it.

I have found the cause of the problem, by the way: T265043#6530768. I'm not sure though what the proper solution is...

Please also see this topic on MediaWiki.

For me, the cause was the ModSecurity WAP used by Namecheap.

Hopefully this would help pinpoint or at least narrow down the issue for others.

@Rehman

If you are talking about the 403 error in my case that's the issue: T265043#6530768

I had a similar issue and I got over it. In my case I encountered a similar error Error contacting the Parsoid/RESTBase server: http-bad-status. I can tell that it's definitely the issue of rewrite(Nginx users probably, like me). But I had another issue as well, I had restricted the access via the Cloudflare's firewall by allowing only one IP address to have access for development purpose of course.
What I did was I included this in my Nginx config to make sure rest.php works even with a trailing slash:

location /wiki/rest.php/ {
    try_files $uri $uri/ /wiki/rest.php?$query_string;
}

Also, I had installed in a different directory rather than the main so be sure to include that directory as well just like what I did.

As I remember zero config Parsoid worked for me for some time in 1.35-alpha then broke.

Basic operation of VisualEditor in MediaWiki 1.35 and later does not require any manual configuration.

And yet http://localhost/w/rest.php/localhost/v3/page/html/Main_Page/81?redirect=false&stash=true returned:
{"messageTranslations":{"en":"The requested relative path (/localhost/v3/page/html/Main_Page/81) did not match any known handler"},"httpCode":404,"httpReason":"Not Found"}

After spending several hours searching for clues it turns out loading the included parsoid is still necessary as of now:
LocalSettings.php:
wfLoadExtension( 'Parsoid', 'vendor/wikimedia/parsoid/extension.json' );

I assume this is unintended. Hopefully this helps somebody.

@Demian loading and installing the parsoid extension isn't necessary, but it does serve to effectively work around some problems that cause visual editor autoconfiguration to be disabled -- usually the presence of manual parsoid configuration in your old local settings.

What workaround do you mean?
Btw, I've removed all config related to parsoid: $wgParsoidSettings, $wgEnableRestAPI, $wgVirtualRestConfig['modules']['parsoid']

@cscott I think it's worth mentioning in the VE documentation that explicitly loading Parsoid might be necessary.
I don't have the full picture of when this is the case. For me it's a necessity and not knowing this caused many lost hours of debugging. Could you add this to the documentation?

@Demian loading and installing the parsoid extension isn't necessary,

I'm sorry I didn't mention I'm developing on 1.36-alpha (or master or nightly)...
https://gerrit.wikimedia.org/r/c/mediawiki/extensions/VisualEditor/+/622187 "Remove Parsoid integration hack, added for 1.35 LTS"

I'm sorry I didn't mention I'm developing on 1.36-alpha (or master or nightly)...
https://gerrit.wikimedia.org/r/c/mediawiki/extensions/VisualEditor/+/622187 "Remove Parsoid integration hack, added for 1.35 LTS"

You should be following the "for developers" information then, which explicitly does ask you to install the Parsoid extension. This task should be for issues with the LTS release version of Parsoid.

I did add some explicit text warning that developers and those with existing parsoid configurations need to install Parsoid manually, I'd try to clarify this more.

The problem is I can't find a "for developers" section. 1) https://www.mediawiki.org/wiki/Extension:VisualEditor#Linking_with_Parsoid had no information for developers before I've added it. 2) I assume you're referring to https://www.mediawiki.org/wiki/Parsoid#Linking_a_developer_checkout_of_Parsoid , however I'm not using a developer checkout. I've used those settings until 1.35 automated it. It seems to me that sections is quite outdated and hardly any of those settings are still necessary, altogether it is quite confusing in the current form, thus it did not help with my issue.
Note: I didn't know the automation was removed in 1.36 until I found the patch. Well hidden. Some form of notification in the docs and email list would have been necessary.
With all these 404 errors in one bucket it's hard to tell what's the root of the issue and this one is quite unexpected. I'll open a specific ticket to document this one.

I did add some explicit text warning that developers and those with existing parsoid configurations need to install Parsoid manually, I'd try to clarify this more.

That would be helpful.
Btw, what workaround did you mean?

Sorry to hijack this post, but I'm getting this error message as well. I suspect it has something to do with editing the LocalSettings file to get shorter wiki links as described in T270376, but I can't be too sure. I think I've configured my wiki to be a private wiki, but I'm not sure if that affects it as well, as I had the issue before I even changed the editing permissions.

Looking into the detailed log in my setup reveals the following behavior:

[http] GET: http://localhost:8181/w/rest.php/localhost/v3/page/html/Main_Page/144730?redirect=false&stash=true
[http] Error fetching URL "http://localhost:8181/w/rest.php/localhost/v3/page/html/Main_Page/144730?redirect=false&stash=true": (curl error: 7) Couldn't connect to server

I am running Mediawiki in a Docker container via the official 1.35 image. On the outside of the Docker network, the wiki's base URL is indeed http://localhost:8181, but from inside the Docker network, from the perspective of the PHP script that tries to call the REST API, the base URL is http://localhost, on standard port 80.

So I believe once parsoid stops calling itself via CURL this issue will be gone. The pattern of assuming URLs and host names are globally accessible is in a few part of Mediawiki/Wikibase, for instance T264009, and makes it hard to run in containers and create portable development and testing environments. If for scalability reasons components are implemented as web services, it would be good to be able to set URLs and hostnames independently from the global wiki URL and hostname.

I can confirm this doesn't work out of the box. I've worked with Mediawiki from 2004-2011 with wikiHow - for context, and this is what I've been able to find on my end. I'm attempting to install this on a wikifarm (without SSL - yet) with nginx.

I've added this to my nginx config:

location /rest.php {
  try_files $uri $uri/ /rest.php?$args;
}

This URL works:

http://www.mywiki.com/rest.php/v1/page/Main_Page

Changing the version to 3 does not work, it 404s.

http://www.mywiki.com/rest.phpv3/page/Main_Page

When the VisualEditor is loaded, it tries to load this API URL:

http://www.mywiki.com/api.php?action=visualeditor&format=json&paction=parse&page=Main_Page&uselang=en&formatversion=2&oldid=27771

This returns a apierror-visualeditor-docserver-http, because the ApiVisualEditor is trying to load this URL:

http://www.mywiki.com/rest.php/www.mywiki.com/v3/page/html/Main_Page/27771?redirect=false&stash=true

Which 404s.

In Router::execute, $relPath is returned as:

/www.mywiki.com/v3/page/html/Main_Page/27771

So it seems the server_name is working correctly on nginx in place of the Apache2 ServerAlias directive.

PathMatcher::match returns null from Router::execute, which I believe throws the 404.

In PathMatcher::match, I see:

$parts = explode( '/', $path );

which creates:

Array
(
    [0] =>
    [1] => www.mywiki.com
    [2] => v3
    [3] => page
    [4] => html
    [5] => Main_Page
    [6] => 27771
)

but in this code block, when the for loop hits www.mywiki.com, it returns false.

foreach ( $parts as $part ) {
  if ( isset( $node["=$part"] ) ) {
    $node = $node["=$part"];
  } elseif ( isset( $node['*'] ) ) {
    $node = $node['*'];
    $paramValues[] = $part;
  } else {
    # RIGHT HERE
    return false;
  }
}

So what's the real problem? Is the API calling the wrong URL or is the Rest service not processing the request properly? Is there a version mismatch issue? Why does v3 work but v1 does not? Also, it seems there are no varations between the two URLs that work either, the following don't work:

http://www.mywiki.com/rest.php/www.mywiki.com/v1/page/html/Main_Page/27771?redirect=false&stash=true
http://www.mywiki.com/rest.php/v1/page/html/Main_Page/27771?redirect=false&stash=true
http://www.mywiki.com/rest.php/v1/page/Main_Page/27771?redirect=false&stash=true

etc