Rails app intermittently failing due to initial request

Problem description:
A Rails app Replit that’s part of an ongoing project since September 2022 has started randomly failing to start due to inconsistent root page fetch behaviour. When the Replit environment starts the Rails server it attempts to load the root page. Sometimes this sends an OPTIONS /* request, which generates a Rails error. The error is only displayed in the console and the webview remains blank. Repeatedly stopping and starting the server eventually leads to a normal GET request and the site works.

Expected behavior:
Pressing the start button starts the Rails server and shows the root page in the webview.

Actual behavior:
Pressing the start buttons starts the Rails server and doesn’t show anything in the webview.

Steps to reproduce:

  1. Open a Rails project.
  2. Observe behaviour.
  3. See the following in console output:
 rails server --binding=0.0.0.0
=> Booting Puma
=> Rails 7.0.1 application starting in development 
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 5.6.0 (ruby 3.0.3-p157) ("Birdie's Version")
*  Min threads: 5
*  Max threads: 5
*  Environment: development
*          PID: 68
* Listening on http://0.0.0.0:3000
Use Ctrl-C to stop
Started OPTIONS "*" for 172.31.128.1 at 2023-01-05 16:46:47 +0000
Cannot render console from 172.31.128.1! Allowed networks: 127.0.0.0/127.255.255.255, ::1
   (1.4ms)  SELECT sqlite_version(*)
  ActiveRecord::SchemaMigration Pluck (0.1ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
  
ActionController::RoutingError (No route matches [OPTIONS] "/*"):

Bug appears at this link:

Browser/OS/Device:
Vivaldi 5.6.2867.50 (Stable channel) (arm64) on Apple Macbook Pro M1 with MacOS 13.1.

Hi @Odaeus thanks for getting in touch. Can you please share a link to the Repl?

Hi Ian, here’s the private Repl in question: https://replit.com/@humboldt-2223/The-Bakery
Can confirm the issue is still present.

It was deleted due to the anti spam plugin thinking it’s spam. I marked it as not spam

1 Like

Just wanted to check-in in case anyone knows of a workaround for this issue? I teach my students again tomorrow and this issue is pretty confusing for them. Maybe a config setting I can tweak?

Apparently I could install and configure a gem for Rails called rack-cors to handle this but I think this would take up most of the lesson time.

Ok! You’ve been really helpful and I’ve been able to get it to work after running the kill 1 command.

I think it is somehow caching previous executions of the pages and this is where it is getting stuck. I’m a bit rusty with rails but will investigate further tomorrow!

About 3 of us out of 10 encountered this issue in the class. Trying kill 1 to reboot the container doesn’t work but I found a clumsy strategy that does:

  1. Comment out the run line in the .replit file.
  2. Wait for the run process to crash.
  3. Restore the run line and press the “Run” button.

For whatever reason, this often (but not always) results in a successful GET request so the Rails server can continue running for that session.

I had one other student who’s server would start but they didn’t get even the failing OPTIONS request, simply nothing happens after Rails starts listening.

Just want to note that I’ve tried adding a routing line to config/routes.rb to intercept the unwanted OPTIONS request:

match '/*' => "home#index", via: :options

Which now makes the server respond to the request (visible in the console) but still Replit cannot load the page in the webview and determine the status as “started”.

Hey @Odaeus!

I have asked the team about this issue and will revert back once I have an answer!

The team has confirmed that the OPTIONS request comes from our webview and our internal proxy. This actually due to CORS, and there isn’t much we can do about this.

Thanks for looking into it! Do you have time to elaborate any further? It worked fine for months until January? Perhaps there is a workaround… Is there a way to disable this initial request so that Replit just assumes it has started? Why does it work roughly 60% of the time? Even if I modify the app to reply to the OPTIONS request it still doesn’t work, is it looking for a special response?
I’m happy to help with debugging where I can.

There isn’t anything we can do as it is part of our Proxy infrastructure to send an OPTIONS request to make sure the site is up. We suggest handling the OPTIONS request in your Rails app as such as request is also common among different browsers.

1 Like

I very much appreciate that Replit is a free platform so I understand I’m not entitled to anything. I did sign up to the educational teams feature when it was a paid option and have been working with this class for several months, so it’s disappointing for my students that it has suddenly stopped working reliably.

Even if I configure Rails specially to respond with 200 OK to any OPTIONS request, it ends up in the same place:

I can’t wrap my head around that this is something the Replit proxy does, but only maybe 60% of the time, and it only started doing it a month ago.

Is there any way for me to determine why the proxy is not issuing the initial GET request? I’m not even convinced that an OPTIONS with an HTTP error response is a failure condition. Even when I carefully craft a response with Allow: OPTIONS, GET, HEAD, POST, it still ends up “frozen”:


(the penultimate line is debug output of the response object)

With a brand new Rails project, the OPTIONS request is sent, returns HTTP 404, but then a GET is still made to load the home page.

We are still investigating this issue. If you add the Access-Control-Allow-Origin: * header to the response fo an OPTIONS request? That should fix things or at least get us somewhere!

2 Likes

I am experiencing the same issue. After adding the Access-Control-Allow-Origin header, the options error message disappears but often the server continues to not serve requests (I am assuming replit is not recognizing it is running).

One additional, possibly related issue, is that the server won’t stop and stay stopped. If I click stop, it will stop and then immediately start again. The only way to get it to stay stopped is to comment out the “run” command in .replit.

This issue is causing me to go elsewhere with my project. I can’t afford to waste 5 min fiddling with the server to get it to respond correctly each time I change a file.

1 Like

Sorry for the delay, I was on holiday. Can verify with @ChrisSmoak that setting the header (I used response.set_header() in the responding controller action) makes no difference.

1 Like

Thank you for the information. I have reproduced this issue and have sent it to the team. I will revert back once I have an update.

3 Likes

Looks like the issue is in application.rb
repl.co instead of replit.com

3 Likes

Not a member of the class in question, but I found this thread since I was having the same issue.

@ chris-intelatek’s reply helped me.

This is an issue with Replit’s default configuration in application.rb as he mentioned.

I changed it to the following which disables the framing protection completely:

    config.action_dispatch.default_headers = {
      'X-Frame-Options' => 'ALLOWFROM *'
    }

But perhaps a more conservative option exists? Replit seems to always show in an iframe, so preventing framing will cause issues.

2 Likes

Hey guys - I’m having the same issue

I’ve tried changing the config both to:

config.action_dispatch.default_headers = {
      'X-Frame-Options' => 'ALLOWFROM replit.co'
    }

and

 config.action_dispatch.default_headers = {
      'X-Frame-Options' => 'ALLOWFROM *'
    }

and

config.action_dispatch.default_headers['X-Frame-Options'] = 'SAMEORIGIN'

But I still get the “ActionController::RoutingError (No route matches [OPTIONS] “/*”):” Any idea why + how to fix this?