A site's own Services.json applies to every publication of the folder

Pitfall By design
A site's own #/Services.json lives in the site FOLDER, not in one publication, so every publication of that folder picks it up — including publications on a different app that does not have the scripts it names, which then fail with "Script file not found".
Applies to: ServicesServices.jsonScheduled tasksAppsPublishing

What you'll see

You want to try a new scheduled service on one site before it goes into the app, so you give the site its own #/Services.json — for example with docly.saveJson("#/Services.json", …). Shortly after, the console fills with errors such as:

Scheduled task failed, Mail poller, Script file not found: #/Services/poll_imap.js

The scripts are in the app's Services/ folder and the site you meant still finds them. The errors come from other publications of the same folder that use a different app. They show up in the same console because the console belongs to the folder, not to one publication. Deleting the file makes them stop.

What's actually happening

The scheduler registers services per publication. Each publication looks up #/Services.json through its own layers: its own # folder first, then its app. It then runs every schedule as #/Services/<Task.Path>, resolved through the same layers.

A folder can be published more than once, for example an admin site on one app and a public front-end on another. The publications share the folder, so they share its # folder. A Services.json placed there:

  • shadows the Services.json of every app used by those publications, not just the one you meant, and
  • runs on every publication. Where the publication's app has no matching script, the task fails with Script file not found, and the task is suspended after MaxRetries failures.

A publication whose app had its own schedules also loses those schedules, silently, for as long as the file is there.

This is by design: # belongs to the folder. The lookup of a script still falls back to the app when the site has no script of its own. That part is not affected by having your own Services.json.

What to do

Before adding #/Services.json to a site, check how many publications the folder has. docly published <folder> lists each one with its app.

  • One publication, or all on the same app: an own Services.json is the right way to override the schedules for that site. Scripts you do not override still come from the app's Services/.
  • Several publications on different apps: the file applies to all of them. Either put every script the file names in the site's own #/Services/ folder, so every publication can find them, or test the new service on a folder that is published only once.

When errors appear, read the Site on the console line or the system log entry (Service: <name> in <url>). It names the publication that failed, which may not be the one you are looking at.

When you are done testing, remove the site's own Services.json. Otherwise the publications on other apps keep running the copied schedules instead of their own.