Scheduled posts won't publish

If you’re looking for some help, it’s important to provide as much context as possible so that people are able to assist you. Try to always mention:

  • What version of Ghost are you using?

  • What configuration?
    Self hosted

  • What browser?

  • What steps could someone else take to reproduce the issue you’re having?
    Create a scheduled post for a couple of minutes in the future. It remains scheduled with a time when it should have been posted.

  • What errors or information do you see in the console?
    [2019-09-05 20:39:35] INFO “PUT /ghost/api/v2/admin/posts/5d716fb6be5aff066857ba54/” 200 412ms
    [2019-09-05 20:41:59] ERROR

NAME: InternalServerError
MESSAGE: The server has encountered an error.

level: critical

InternalServerError: The server has encountered an error.
at new GhostError (/var/www/ghost/versions/2.25.8/core/server/lib/common/errors.js:10:26)
at request.catch (/var/www/ghost/versions/2.25.8/core/server/adapters/scheduling/SchedulingDefault.js:349:30)
at tryCatcher (/var/www/ghost/versions/2.25.8/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/var/www/ghost/versions/2.25.8/node_modules/bluebird/js/release/promise.js:517:31)
at Promise._settlePromise (/var/www/ghost/versions/2.25.8/node_modules/bluebird/js/release/promise.js:574:18)
at Promise._settlePromiseCtx (/var/www/ghost/versions/2.25.8/node_modules/bluebird/js/release/promise.js:611:10)
at _drainQueueStep (/var/www/ghost/versions/2.25.8/node_modules/bluebird/js/release/async.js:142:12)
at _drainQueue (/var/www/ghost/versions/2.25.8/node_modules/bluebird/js/release/async.js:131:9)
at Async._drainQueues (/var/www/ghost/versions/2.25.8/node_modules/bluebird/js/release/async.js:147:5)
at Immediate.Async.drainQueues [as _onImmediate] (/var/www/ghost/versions/2.25.8/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)

InternalServerError: URL empty or invalid.
at new InternalServerError (/var/www/ghost/versions/2.25.8/node_modules/ghost-ignition/lib/errors/index.js:77:23)
at request (/var/www/ghost/versions/2.25.8/core/server/lib/request.js:15:31)
at SchedulingDefault._pingUrl (/var/www/ghost/versions/2.25.8/core/server/adapters/scheduling/SchedulingDefault.js:325:12)
at /var/www/ghost/versions/2.25.8/core/server/adapters/scheduling/SchedulingDefault.js:283:30
at Array.forEach ()
at Immediate._onImmediate (/var/www/ghost/versions/2.25.8/core/server/adapters/scheduling/SchedulingDefault.js:268:31)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)

[2019-09-05 20:42:18] INFO “GET /favicon.ico?t=1567716137998” 200 2ms

Hey there :wave:
Can I ask where this is being hosted? Is it local development? Thanks!

It’s being hosted on an internal site.

Have you tried running ghost doctor to see what it says? Might help to debug the issue :smiley:

Yes, the only errors that came back from ghost doctor were permissions with images. We use nfs to mount images.

The default scheduler requires the ability to make an HTTP request to the API in order to publish the post. It looks like that HTTP request is failing - the error you are getting says that the url that the scheduler is attempting to ping is missing or invalid.

Is this the real URL your site is configured with?

The main way to debug the scheduler is connecting to your server via terminal and using curl to ping the API - if it’s able to make a successful request, the scheduler should be fine.

1 Like

The ghost user using * curl http://ghostcms ` gives me a valid response.

Ah ok - that makes sense.

In that case the problem is that the default scheduling adapter uses our internal request module, and that in turn validates the URL using validator. Validator doesn’t consider the URL to be valid, so the request doesn’t get attempted.

Your options are:

  1. change the URL to be something that validator understands
  2. write your own scheduling adapter that uses your own request/validation code
  3. submit a patch to Ghost so that validation happens only if the request fails (to return a useful more error)

const validator = require(‘validator’);

console.log(validator.isURL(‘http://ghostcms’, {require_tld: false}));

console.log(validator.isURL(‘http://ghostcms’, {require_tld: true}));

To be honest, I think you’d be better off using a domain with a TLD.

Your problem is an edge case, as I’ve mentioned on the PR I don’t think the patch is the correct fix. Patching was deliberately option 3 - it’s not gonna be an easy thing to resolve with a PR :slight_smile:

If the domain can’t be changed, a custom scheduling adapter would let you fix the problem immediately, without needing to get a patch approved, merged & released.

1 Like