diff --git a/docs/configuration.md b/docs/configuration.md
index ee0dc18522dd19ad5a3da4ca61cf09ce0baa87ae..3fff9b9474bc37f1309a523db6c10faf65908241 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -539,7 +539,7 @@ Obviously, you can't set repository or package file location with this method.
   "commitMessage": "{{semanticPrefix}}Update lock file",
   "prTitle": "{{semanticPrefix}}Lock file maintenance",
   "prBody": "This {{#if isGitHub}}Pull{{else}}Merge{{/if}} Request updates `package.json` lock files to use the latest dependency versions.\n\n{{#if schedule}}\n**Note**: This PR was created on a configured schedule (\"{{schedule}}\"{{#if timezone}} in timezone `{{timezone}}`{{/if}}) and will not receive updates outside those times.\n{{/if}}\n\n{{#if hasErrors}}\n\n---\n\n### Errors\n\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\n\n{{#each errors as |error|}}\n-   `{{error.depName}}`: {{error.message}}\n{{/each}}\n{{/if}}\n\n{{#if hasWarnings}}\n\n---\n\n### Warnings\n\nPlease make sure the following warnings are safe to ignore:\n\n{{#each warnings as |warning|}}\n-   `{{warning.depName}}`: {{warning.message}}\n{{/each}}\n{{/if}}\n\n---\n\nThis {{#if isGitHub}}PR{{else}}MR{{/if}} has been generated by [Renovate Bot](https://renovateapp.com).",
-  "schedule": "before 5am on monday"
+  "schedule": ["before 5am on monday"]
 }</pre></td>
   <td>`RENOVATE_LOCK_FILE_MAINTENANCE`</td>
   <td><td>
diff --git a/docs/faq.md b/docs/faq.md
index b9f46e07c4e191ba2f54b09941b49624bafa0fa7..80f2d3f862c2033d3e1d705f169ea74b587b8cc3 100644
--- a/docs/faq.md
+++ b/docs/faq.md
@@ -74,11 +74,13 @@ To restrict `aws-sdk` to only weekly updates, you could add this package rule:
   "packages": [
     {
       "packageName": "aws-sdk",
-      "schedule": "after 9pm on sunday"
+      "schedule": ["after 9pm on sunday"]
     }
   ]
 ```
 
+Note that schedule must be in the form of an array, even if only one schedule is present. Multiple entries in the array means "or".
+
 ### Selectively enable or disable renovate for specific `package.json` files
 
 You could:
@@ -104,7 +106,7 @@ Set configuration option `pinVersions` to `false`.
 
 ### Keep `yarn.lock` sub-dependencies up-to-date, even when `package.json` hasn't changed
 
-This is enabled by default, but its schedule is set to 'before 5am on monday'. If you want it more frequently, then update the `schedule` field inside the `lockFileMaintenance` object.
+This is enabled by default, but its schedule is set to `['before 5am on monday']`. If you want it more frequently, then update the `schedule` field inside the `lockFileMaintenance` object.
 
 ### Wait until tests have passed before creating the PR
 
diff --git a/lib/config/definitions.js b/lib/config/definitions.js
index 4db8770badac9a5e0d24ae599d71dfa1b054abb3..25bd51866ee4715e84806f5295f87dfcb51b5e15 100644
--- a/lib/config/definitions.js
+++ b/lib/config/definitions.js
@@ -393,7 +393,7 @@ const options = [
       commitMessage: template('commitMessage', 'lock-file-maintenance'),
       prTitle: template('prTitle', 'lock-file-maintenance'),
       prBody: template('prBody', 'lock-file-maintenance'),
-      schedule: 'before 5am on monday',
+      schedule: ['before 5am on monday'],
     },
     cli: false,
     mergeable: true,
diff --git a/lib/config/migration.js b/lib/config/migration.js
index eb2376f8dc6d4c19350ee46eb37beb4df045d016..473a0fe75eadf86e485d181c970e4f3aa585f8f4 100644
--- a/lib/config/migration.js
+++ b/lib/config/migration.js
@@ -24,6 +24,9 @@ function migrateConfig(config) {
     if (removedOptions.includes(key)) {
       isMigrated = true;
       delete migratedConfig[key];
+    } else if (key === 'schedule' && typeof val === 'string') {
+      isMigrated = true;
+      migratedConfig.schedule = [val];
     } else if (key === 'depTypes' && Array.isArray(val)) {
       val.forEach(depType => {
         if (isObject(depType)) {
diff --git a/lib/config/validation.js b/lib/config/validation.js
index 41de8f0edbc179739cffc3487429f0b73d457c28..50620cf24ec9a9f94b0871efb22fcad21de8ce04 100644
--- a/lib/config/validation.js
+++ b/lib/config/validation.js
@@ -32,7 +32,7 @@ function validateConfig(config) {
   }
 
   for (const key of Object.keys(config)) {
-    let val = config[key];
+    const val = config[key];
     if (
       !isIgnored(key) && // We need to ignore some reserved keys
       !isAFunction(val) // Ignore all functions
@@ -52,9 +52,6 @@ function validateConfig(config) {
             });
           }
         } else if (type === 'list') {
-          if (key === 'schedule' && typeof val === 'string') {
-            val = [val];
-          }
           if (!Array.isArray(val)) {
             errors.push({
               depName: 'Configuration Error',
diff --git a/lib/workers/branch/schedule.js b/lib/workers/branch/schedule.js
index 2d31641592a03bbfca7f17c54203703967ea17ad..e5d2478227c0d2a5f27bfc4478033fe550172975 100644
--- a/lib/workers/branch/schedule.js
+++ b/lib/workers/branch/schedule.js
@@ -47,10 +47,7 @@ function hasValidSchedule(schedule, logger) {
 
 function isScheduledNow(config) {
   config.logger.debug({ schedule: config.schedule }, `Checking schedule`);
-  // Massage into array
-  const configSchedule =
-    typeof config.schedule === 'string' ? [config.schedule] : config.schedule;
-  if (!module.exports.hasValidSchedule(configSchedule, config.logger)) {
+  if (!module.exports.hasValidSchedule(config.schedule, config.logger)) {
     // Return true if the schedule is invalid
     return true;
   }
@@ -70,9 +67,9 @@ function isScheduledNow(config) {
     now.hours() * 3600 + now.minutes() * 60 + now.seconds();
   config.logger.debug(`currentSeconds=${currentSeconds}`);
   // Support a single string but massage to array for processing
-  config.logger.debug(`Checking ${configSchedule.length} schedule(s)`);
+  config.logger.debug(`Checking ${config.schedule.length} schedule(s)`);
   // We run if any schedule matches
-  const isWithinSchedule = configSchedule.some(scheduleText => {
+  const isWithinSchedule = config.schedule.some(scheduleText => {
     config.logger.debug(`Checking schedule "${scheduleText}"`);
     const parsedSchedule = later.parse.text(fixShortHours(scheduleText));
     // Later library returns array of schedules
diff --git a/test/config/__snapshots__/index.spec.js.snap b/test/config/__snapshots__/index.spec.js.snap
index b0d69c50a6a2f3fa2bef7106f6eef213bf57f2f3..db210bdd93da9ef8af9abfa7fbc1532b80cb2aaf 100644
--- a/test/config/__snapshots__/index.spec.js.snap
+++ b/test/config/__snapshots__/index.spec.js.snap
@@ -43,7 +43,9 @@ Please make sure the following warnings are safe to ignore:
 This {{#if isGitHub}}PR{{else}}MR{{/if}} has been generated by [Renovate Bot](https://renovateapp.com).",
   "prTitle": "{{semanticPrefix}}Lock file maintenance",
   "recreateClosed": true,
-  "schedule": "on monday",
+  "schedule": Array [
+    "on monday",
+  ],
 }
 `;
 
diff --git a/test/config/__snapshots__/migration.spec.js.snap b/test/config/__snapshots__/migration.spec.js.snap
index ef00800e7f559a0df7eacac71a483b8c80daa950..e7eebe819404fab8a5fa65bfaedc67afd61b20b6 100644
--- a/test/config/__snapshots__/migration.spec.js.snap
+++ b/test/config/__snapshots__/migration.spec.js.snap
@@ -6,6 +6,9 @@ Object {
   "optionalDependencies": Object {
     "respectLatest": false,
   },
+  "schedule": Array [
+    "after 5pm",
+  ],
 }
 `;
 
diff --git a/test/config/index.spec.js b/test/config/index.spec.js
index 5a23ceb0ea0d91797f313b030279dbd95e4fe1be..2f0bb4ccbe117a28c02ad1f84d70290acc4a8dcf 100644
--- a/test/config/index.spec.js
+++ b/test/config/index.spec.js
@@ -152,14 +152,14 @@ describe('config/index', () => {
         foo: 'bar',
         pinVersions: false,
         lockFileMaintenance: {
-          schedule: 'on monday',
+          schedule: ['on monday'],
         },
       };
       const configParser = require('../../lib/config/index.js');
       const config = configParser.mergeChildConfig(parentConfig, childConfig);
       expect(config.foo).toEqual('bar');
       expect(config.pinVersions).toBe(false);
-      expect(config.lockFileMaintenance.schedule).toEqual('on monday');
+      expect(config.lockFileMaintenance.schedule).toEqual(['on monday']);
       expect(config.lockFileMaintenance).toMatchSnapshot();
     });
     it('merges depTypes', () => {
diff --git a/test/config/migration.spec.js b/test/config/migration.spec.js
index 4e9db9c9a236cdb0ec39069cc557c05ecf3526e5..5e3f8034f48b44ebf960d45a5a6cc2853cf85eaf 100644
--- a/test/config/migration.spec.js
+++ b/test/config/migration.spec.js
@@ -6,6 +6,7 @@ describe('config/migration', () => {
       const config = {
         enabled: true,
         maintainYarnLock: true,
+        schedule: 'after 5pm',
         depTypes: [
           'dependencies',
           {
diff --git a/test/config/validation.spec.js b/test/config/validation.spec.js
index 2e99501e089587a7a380aa3582ad869102c340a1..a5ef8d43dbf163304a76be5f88e645ff88383cbc 100644
--- a/test/config/validation.spec.js
+++ b/test/config/validation.spec.js
@@ -5,7 +5,7 @@ describe('config/validation', () => {
     it('returns nested errors', () => {
       const config = {
         foo: 1,
-        schedule: 'after 5pm',
+        schedule: ['after 5pm'],
         prBody: 'some-body',
         lockFileMaintenance: {
           bar: 2,
diff --git a/test/workers/branch/schedule.spec.js b/test/workers/branch/schedule.spec.js
index 742a72cb229686fae4af5ee780e5c3952a4629f1..98789f23c3ecaddd57910ea7e775ed3ff73552ac 100644
--- a/test/workers/branch/schedule.spec.js
+++ b/test/workers/branch/schedule.spec.js
@@ -87,22 +87,22 @@ describe('workers/branch/schedule', () => {
       expect(res).toBe(true);
     });
     it('supports before hours true', () => {
-      config.schedule = 'before 4:00pm';
+      config.schedule = ['before 4:00pm'];
       const res = schedule.isScheduledNow(config);
       expect(res).toBe(true);
     });
     it('supports before hours false', () => {
-      config.schedule = 'before 4:00am';
+      config.schedule = ['before 4:00am'];
       const res = schedule.isScheduledNow(config);
       expect(res).toBe(false);
     });
     it('supports outside hours', () => {
-      config.schedule = 'after 4:00pm';
+      config.schedule = ['after 4:00pm'];
       const res = schedule.isScheduledNow(config);
       expect(res).toBe(false);
     });
     it('supports timezone', () => {
-      config.schedule = 'after 4:00pm';
+      config.schedule = ['after 4:00pm'];
       config.timezone = 'Asia/Singapore';
       const res = schedule.isScheduledNow(config);
       expect(res).toBe(true);
@@ -113,12 +113,12 @@ describe('workers/branch/schedule', () => {
       expect(res).toBe(true);
     });
     it('supports day match', () => {
-      config.schedule = 'on friday and saturday';
+      config.schedule = ['on friday and saturday'];
       const res = schedule.isScheduledNow(config);
       expect(res).toBe(true);
     });
     it('supports day mismatch', () => {
-      config.schedule = 'on monday and tuesday';
+      config.schedule = ['on monday and tuesday'];
       const res = schedule.isScheduledNow(config);
       expect(res).toBe(false);
     });