diff --git a/lib/config/presets.ts b/lib/config/presets.ts
index d2672521b658bee5018339603d70ab18b7a61b89..986b8518b9cd224dc968c5abd45326ff5d46793e 100644
--- a/lib/config/presets.ts
+++ b/lib/config/presets.ts
@@ -8,6 +8,11 @@ import * as gitlab from '../datasource/gitlab';
 import { RenovateConfig } from './common';
 import { mergeChildConfig } from './utils';
 import { regEx } from '../util/regex';
+import {
+  CONFIG_VALIDATION,
+  DATASOURCE_FAILURE,
+  PLATFORM_FAILURE,
+} from '../constants/error-messages';
 
 const datasources = {
   github,
@@ -166,12 +171,12 @@ export async function resolveConfigPresets(
           logger.debug({ err }, 'Preset fetch error');
           // istanbul ignore if
           if (
-            err.message === 'platform-failure' ||
-            err.message === 'registry-failure'
+            err.message === PLATFORM_FAILURE ||
+            err.message === DATASOURCE_FAILURE
           ) {
             throw err;
           }
-          const error = new Error('config-validation');
+          const error = new Error(CONFIG_VALIDATION);
           if (err.message === 'dep not found') {
             error.validationError = `Cannot find preset's package (${preset})`;
           } else if (err.message === 'preset renovate-config not found') {
diff --git a/lib/constants/error-messages.ts b/lib/constants/error-messages.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8aacceae24b882626e024772a0d4530b2207a4a7
--- /dev/null
+++ b/lib/constants/error-messages.ts
@@ -0,0 +1,47 @@
+// System error
+export const SYSTEM_INSUFFICIENT_DISK_SPACE = 'disk-space';
+
+// Platform Error
+export const PLATFORM_AUTHENTICATION_ERROR = 'authentication-error';
+export const PLATFORM_BAD_CREDENTIALS = 'bad-credentials';
+export const PLATFORM_FAILURE = 'platform-failure';
+export const PLATFORM_INTEGRATION_UNAUTHORIZED = 'integration-unauthorized';
+export const PLATFORM_NOT_FOUND = 'platform-not-found';
+export const PLATFORM_RATE_LIMIT_EXCEEDED = 'rate-limit-exceeded';
+
+// Config Error
+export const CONFIG_VALIDATION = 'config-validation';
+
+// Repository Error
+export const REPOSITORY_ACCESS_FORBIDDEN = 'forbidden';
+export const REPOSITORY_ARCHIVED = 'archived';
+export const REPOSITORY_BLOCKED = 'blocked';
+export const REPOSITORY_CANNOT_FORK = 'cannot-fork';
+export const REPOSITORY_CHANGED = 'repository-changed';
+export const REPOSITORY_DISABLED = 'disabled';
+export const REPOSITORY_EMPTY = 'empty';
+export const REPOSITORY_FORKED = 'fork';
+export const REPOSITORY_MIRRORED = 'mirror';
+export const REPOSITORY_NOT_FOUND = 'not-found';
+export const REPOSITORY_NO_VULNERABILITY = 'no-vulnerability-alerts';
+export const REPOSITORY_RENAMED = 'renamed';
+export const REPOSITORY_TEMPORARY_ERROR = 'temporary-error';
+export const REPOSITORY_UNINITIATED = 'uninitiated';
+
+// Manager Error
+export const MANAGER_LOCKFILE_ERROR = 'lockfile-error';
+export const MANAGER_NO_PACKAGE_FILES = 'no-package-files';
+
+// Datasource error
+export const DATASOURCE_FAILURE = 'registry-failure';
+
+// Worker Error
+export const WORKER_FILE_UPDATE_FAILED = 'update-failure';
+
+// Bundler Error
+export const BUNDLER_COULD_NOT_RESOLVE = 'bundler-resolve';
+export const BUNDLER_INVALID_CREDENTIALS = 'bundler-credentials';
+export const BUNDLER_UNKNOWN_ERROR = 'bundler-unknown';
+
+// Unknown Error
+export const UNKNOWN_ERROR = 'unknown-error';
diff --git a/lib/datasource/cargo/index.ts b/lib/datasource/cargo/index.ts
index 41c65bf4d96c10bc43dda9935058c7772dce5d4a..d36ccdc120729f6f24851dafd6c6fa995cd5c8c6 100644
--- a/lib/datasource/cargo/index.ts
+++ b/lib/datasource/cargo/index.ts
@@ -1,6 +1,7 @@
 import { logger } from '../../logger';
 import got from '../../util/got';
 import { PkgReleaseConfig, ReleaseResult, Release } from '../common';
+import { DATASOURCE_FAILURE } from '../../constants/error-messages';
 
 export async function getPkgReleases({
   lookupName,
@@ -101,7 +102,7 @@ export async function getPkgReleases({
       (err.statusCode >= 500 && err.statusCode < 600)
     ) {
       logger.warn({ lookupName, err }, `cargo crates.io registry failure`);
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     logger.warn(
       { err, lookupName },
diff --git a/lib/datasource/dart/index.ts b/lib/datasource/dart/index.ts
index 2b3723f34b2387e050977fd58f877db9cf92b376..3d7933743ba835b627cdc6724329c370a736610d 100644
--- a/lib/datasource/dart/index.ts
+++ b/lib/datasource/dart/index.ts
@@ -1,6 +1,7 @@
 import got from '../../util/got';
 import { logger } from '../../logger';
 import { ReleaseResult, PkgReleaseConfig } from '../common';
+import { DATASOURCE_FAILURE } from '../../constants/error-messages';
 
 export async function getPkgReleases({
   lookupName,
@@ -34,7 +35,7 @@ export async function getPkgReleases({
       (err.statusCode >= 500 && err.statusCode < 600)
     ) {
       logger.warn({ lookupName, err }, `pub.dartlang.org registry failure`);
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     logger.warn(
       { err, lookupName },
diff --git a/lib/datasource/docker/index.ts b/lib/datasource/docker/index.ts
index 793ee45cbb97d38a1539cbdf579790540b8051ab..564b81583638f8ffe6996802c882db7b527b1351 100644
--- a/lib/datasource/docker/index.ts
+++ b/lib/datasource/docker/index.ts
@@ -10,6 +10,7 @@ import got from '../../util/got';
 import * as hostRules from '../../util/host-rules';
 import { PkgReleaseConfig, ReleaseResult } from '../common';
 import { GotResponse } from '../../platform';
+import { DATASOURCE_FAILURE } from '../../constants/error-messages';
 
 // TODO: add got typings when available
 // TODO: replace www-authenticate with https://www.npmjs.com/package/auth-header ?
@@ -162,15 +163,15 @@ async function getAuthHeaders(
     if (err.name === 'RequestError' && registry.endsWith('docker.io')) {
       logger.debug({ err }, 'err');
       logger.info('Docker registry error: RequestError');
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     if (err.statusCode === 429 && registry.endsWith('docker.io')) {
       logger.warn({ err }, 'docker registry failure: too many requests');
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     if (err.statusCode >= 500 && err.statusCode < 600) {
       logger.warn({ err }, 'docker registry failure: internal error');
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     logger.warn(
       { registry, dockerRepository: repository, err },
@@ -210,7 +211,7 @@ async function getManifestResponse(
     });
     return manifestResponse;
   } catch (err) /* istanbul ignore next */ {
-    if (err.message === 'registry-failure') {
+    if (err.message === DATASOURCE_FAILURE) {
       throw err;
     }
     if (err.statusCode === 401) {
@@ -235,7 +236,7 @@ async function getManifestResponse(
     }
     if (err.statusCode === 429 && registry.endsWith('docker.io')) {
       logger.warn({ err }, 'docker registry failure: too many requests');
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     if (err.statusCode >= 500 && err.statusCode < 600) {
       logger.info(
@@ -247,7 +248,7 @@ async function getManifestResponse(
         },
         'docker registry failure: internal error'
       );
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     if (err.code === 'ETIMEDOUT') {
       logger.info(
@@ -311,7 +312,7 @@ export async function getDigest(
     await renovateCache.set(cacheNamespace, cacheKey, digest, cacheMinutes);
     return digest;
   } catch (err) /* istanbul ignore next */ {
-    if (err.message === 'registry-failure') {
+    if (err.message === DATASOURCE_FAILURE) {
       throw err;
     }
     logger.info(
@@ -366,7 +367,7 @@ async function getTags(
     await renovateCache.set(cacheNamespace, cacheKey, tags, cacheMinutes);
     return tags;
   } catch (err) /* istanbul ignore next */ {
-    if (err.message === 'registry-failure') {
+    if (err.message === DATASOURCE_FAILURE) {
       throw err;
     }
     logger.debug(
@@ -393,14 +394,14 @@ async function getTags(
         { registry, dockerRepository: repository, err },
         'docker registry failure: too many requests'
       );
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     if (err.statusCode >= 500 && err.statusCode < 600) {
       logger.warn(
         { registry, dockerRepository: repository, err },
         'docker registry failure: internal error'
       );
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     if (err.code === 'ETIMEDOUT') {
       logger.info(
@@ -524,7 +525,7 @@ async function getLabels(
     await renovateCache.set(cacheNamespace, cacheKey, labels, cacheMinutes);
     return labels;
   } catch (err) {
-    if (err.message === 'registry-failure') {
+    if (err.message === DATASOURCE_FAILURE) {
       throw err;
     }
     if (err.statusCode === 401) {
diff --git a/lib/datasource/gradle-version/index.ts b/lib/datasource/gradle-version/index.ts
index e0b42e3511540e7a1b379f23ce00b828b82f8920..5c0006f27189b3c6241e6b8de32e69c8077a38ed 100644
--- a/lib/datasource/gradle-version/index.ts
+++ b/lib/datasource/gradle-version/index.ts
@@ -3,6 +3,7 @@ import is from '@sindresorhus/is';
 import { logger } from '../../logger';
 import got from '../../util/got';
 import { PkgReleaseConfig, ReleaseResult, Release } from '../common';
+import { DATASOURCE_FAILURE } from '../../constants/error-messages';
 
 const GradleVersionsServiceUrl = 'https://services.gradle.org/versions/all';
 
@@ -48,7 +49,7 @@ export async function getPkgReleases({
         if (!(err.statusCode === 404 || err.code === 'ENOTFOUND')) {
           logger.warn({ err }, 'Gradle release lookup failure: Unknown error');
         }
-        throw new Error('registry-failure');
+        throw new Error(DATASOURCE_FAILURE);
       }
     })
   );
diff --git a/lib/datasource/helm/index.ts b/lib/datasource/helm/index.ts
index 5913f5ca3f8e91f7d58b38a2c59e79a2a24a091e..8552b09cb6bc7acf123d5e6a2a2646e37cb382ba 100644
--- a/lib/datasource/helm/index.ts
+++ b/lib/datasource/helm/index.ts
@@ -1,4 +1,5 @@
 import yaml from 'js-yaml';
+import { DATASOURCE_FAILURE } from '../../constants/error-messages';
 
 import { PkgReleaseConfig, ReleaseResult } from '../common';
 import got from '../../util/got';
@@ -35,7 +36,7 @@ export async function getRepositoryData(
       (err.statusCode >= 500 && err.statusCode < 600)
     ) {
       logger.warn({ err }, `${repository} server error`);
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     logger.warn({ err }, `${repository} lookup failure: Unknown error`);
     return null;
diff --git a/lib/datasource/hex/index.ts b/lib/datasource/hex/index.ts
index 85cfa46d4f5b05c681baf1df334e057f088e1efe..999ec4eb5f4831ec7ac9b93b62f626d5d727c1a9 100644
--- a/lib/datasource/hex/index.ts
+++ b/lib/datasource/hex/index.ts
@@ -1,6 +1,7 @@
 import { logger } from '../../logger';
 import got from '../../util/got';
 import { ReleaseResult, PkgReleaseConfig } from '../common';
+import { DATASOURCE_FAILURE } from '../../constants/error-messages';
 
 interface HexRelease {
   html_url: string;
@@ -65,7 +66,7 @@ export async function getPkgReleases({
       (err.statusCode >= 500 && err.statusCode < 600)
     ) {
       logger.warn({ lookupName, err }, `hex.pm registry failure`);
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
 
     if (err.statusCode === 401) {
diff --git a/lib/datasource/maven/util.ts b/lib/datasource/maven/util.ts
index 4ca420875101c8617be3184bd0d9126fcb60000a..a06b0cf83745193a79b08334b6bc183cabbb2e36 100644
--- a/lib/datasource/maven/util.ts
+++ b/lib/datasource/maven/util.ts
@@ -1,6 +1,7 @@
 import url from 'url';
 import got from '../../util/got';
 import { logger } from '../../logger';
+import { DATASOURCE_FAILURE } from '../../constants/error-messages';
 
 function isMavenCentral(pkgUrl: url.URL | string): boolean {
   return (
@@ -70,7 +71,7 @@ export async function downloadHttpProtocol(
     } else if (isTemporalError(err)) {
       logger.info({ failedUrl, err }, 'Temporary error');
       if (isMavenCentral(pkgUrl)) {
-        throw new Error('registry-failure');
+        throw new Error(DATASOURCE_FAILURE);
       }
     } else if (isConnectionError(err)) {
       // istanbul ignore next
diff --git a/lib/datasource/npm/get.ts b/lib/datasource/npm/get.ts
index ab2f8010141c94d6bf3c5e6713adc07d95c0a476..3facf873c31de6407084c6528ef73293e2c7b1a9 100644
--- a/lib/datasource/npm/get.ts
+++ b/lib/datasource/npm/get.ts
@@ -10,6 +10,7 @@ import got from '../../util/got';
 import { maskToken } from '../../util/mask';
 import { getNpmrc } from './npmrc';
 import { Release, ReleaseResult } from '../common';
+import { DATASOURCE_FAILURE } from '../../constants/error-messages';
 
 let memcache = {};
 
@@ -234,7 +235,7 @@ export async function getDependency(
     }
     if (regUrl.startsWith('https://registry.npmjs.org')) {
       logger.warn({ err, regUrl, depName: name }, 'npm registry failure');
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     // istanbul ignore next
     return null;
diff --git a/lib/datasource/packagist/index.ts b/lib/datasource/packagist/index.ts
index 281d793c8764cfe703b7a48dfb37c00f5c3c2491..bad5aefb52e95e49ca5889281bb1be72dfd1f36c 100644
--- a/lib/datasource/packagist/index.ts
+++ b/lib/datasource/packagist/index.ts
@@ -8,6 +8,7 @@ import { logger } from '../../logger';
 import got, { GotJSONOptions } from '../../util/got';
 import * as hostRules from '../../util/host-rules';
 import { PkgReleaseConfig, ReleaseResult } from '../common';
+import { DATASOURCE_FAILURE } from '../../constants/error-messages';
 
 function getHostOpts(url: string): GotJSONOptions {
   const opts: GotJSONOptions = {
@@ -287,7 +288,7 @@ async function packageLookup(
       err.host === 'packagist.org'
     ) {
       logger.info('Packagist.org timeout');
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     logger.warn({ err, name }, 'packagist registry failure: Unknown error');
     return null;
diff --git a/lib/datasource/ruby-version/index.ts b/lib/datasource/ruby-version/index.ts
index ffcbbe50c04682b13058dba947133694c48809ac..39154e7fe1344b2f1898807d68c7bd1d9e1ba129 100644
--- a/lib/datasource/ruby-version/index.ts
+++ b/lib/datasource/ruby-version/index.ts
@@ -4,6 +4,7 @@ import { logger } from '../../logger';
 import got from '../../util/got';
 import { isVersion } from '../../versioning/ruby';
 import { PkgReleaseConfig, ReleaseResult } from '../common';
+import { DATASOURCE_FAILURE } from '../../constants/error-messages';
 
 const rubyVersionsUrl = 'https://www.ruby-lang.org/en/downloads/releases/';
 
@@ -48,9 +49,9 @@ export async function getPkgReleases(
     return res;
   } catch (err) {
     if (err && (err.statusCode === 404 || err.code === 'ENOTFOUND')) {
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     logger.warn({ err }, 'Ruby release lookup failure: Unknown error');
-    throw new Error('registry-failure');
+    throw new Error(DATASOURCE_FAILURE);
   }
 }
diff --git a/lib/datasource/rubygems/get-rubygems-org.ts b/lib/datasource/rubygems/get-rubygems-org.ts
index 3b9c1491999d96779d3a5a38302582d2d331e309..208f814fd55743b97dce8e32bcfda5d9ae261bc5 100644
--- a/lib/datasource/rubygems/get-rubygems-org.ts
+++ b/lib/datasource/rubygems/get-rubygems-org.ts
@@ -1,6 +1,7 @@
 import got from '../../util/got';
 import { logger } from '../../logger';
 import { ReleaseResult } from '../common';
+import { DATASOURCE_FAILURE } from '../../constants/error-messages';
 
 let lastSync = new Date('2000-01-01');
 let packageReleases: Record<string, string[]> = Object.create(null); // Because we might need a "constructor" key
@@ -26,7 +27,7 @@ async function updateRubyGemsVersions(): Promise<void> {
       logger.warn({ err }, 'Rubygems error - resetting cache');
       contentLength = 0;
       packageReleases = Object.create(null); // Because we might need a "constructor" key
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     logger.debug('Rubygems: No update');
     lastSync = new Date();
diff --git a/lib/datasource/rubygems/get.ts b/lib/datasource/rubygems/get.ts
index a851facda09e5821f6da6d4ccd1b64c9b433d949..76a627b7b4debc216e1710971ad75d769a59cb0d 100644
--- a/lib/datasource/rubygems/get.ts
+++ b/lib/datasource/rubygems/get.ts
@@ -5,6 +5,7 @@ import { maskToken } from '../../util/mask';
 import retriable from './retriable';
 import { UNAUTHORIZED, FORBIDDEN, NOT_FOUND } from './errors';
 import { ReleaseResult } from '../common';
+import { DATASOURCE_FAILURE } from '../../constants/error-messages';
 
 const INFO_PATH = '/api/v1/gems';
 const VERSIONS_PATH = '/api/v1/versions';
@@ -29,7 +30,7 @@ const processError = ({ err, ...rest }): null => {
       break;
     default:
       logger.debug(data, 'RubyGems lookup failure');
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
   }
   return null;
 };
diff --git a/lib/manager/bundler/artifacts.ts b/lib/manager/bundler/artifacts.ts
index 3997a8a7cb0cb431438afd07013b1f971cc9f30e..b1a150562564e84ccb9feec6c45466729c6d1625 100644
--- a/lib/manager/bundler/artifacts.ts
+++ b/lib/manager/bundler/artifacts.ts
@@ -12,6 +12,11 @@ import {
 } from '../../versioning/ruby';
 import { UpdateArtifactsConfig, UpdateArtifactsResult } from '../common';
 import { platform } from '../../platform';
+import {
+  BUNDLER_COULD_NOT_RESOLVE,
+  BUNDLER_INVALID_CREDENTIALS,
+  BUNDLER_UNKNOWN_ERROR,
+} from '../../constants/error-messages';
 
 export async function updateArtifacts(
   packageFileName: string,
@@ -149,8 +154,8 @@ export async function updateArtifacts(
         { err },
         'Gemfile.lock update failed due to missing credentials'
       );
-      global.repoCache.bundlerArtifactsError = 'bundler-credentials';
-      throw new Error('bundler-credentials');
+      global.repoCache.bundlerArtifactsError = BUNDLER_INVALID_CREDENTIALS;
+      throw new Error(BUNDLER_INVALID_CREDENTIALS);
     }
     const resolveMatchRe = new RegExp('\\s+(.*) was resolved to', 'g');
     if (err.stderr && err.stderr.match(resolveMatchRe)) {
@@ -180,10 +185,10 @@ export async function updateArtifacts(
       }
       logger.warn({ err }, 'Cannot resolve bundler lock update error');
       // Do not set global.repoCache because we don't want to stop trying other branches
-      throw new Error('bundler-resolve');
+      throw new Error(BUNDLER_COULD_NOT_RESOLVE);
     }
     logger.warn({ err }, 'Unknown bundler lock file update error');
-    global.repoCache.bundlerArtifactsError = 'bundler-unknown';
-    throw new Error('bundler-unknown');
+    global.repoCache.bundlerArtifactsError = BUNDLER_UNKNOWN_ERROR;
+    throw new Error(BUNDLER_UNKNOWN_ERROR);
   }
 }
diff --git a/lib/manager/composer/artifacts.ts b/lib/manager/composer/artifacts.ts
index a1242ab12b80d4e827298f3799b27a47c0e6ec45..f6a1b3592d8867a28a17d98ce1114aee9d6c25d1 100644
--- a/lib/manager/composer/artifacts.ts
+++ b/lib/manager/composer/artifacts.ts
@@ -8,6 +8,7 @@ import { logger } from '../../logger';
 import * as hostRules from '../../util/host-rules';
 import { getChildProcessEnv } from '../../util/exec/env';
 import { platform } from '../../platform';
+import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../constants/error-messages';
 
 export async function updateArtifacts(
   packageFileName: string,
@@ -166,7 +167,7 @@ export async function updateArtifacts(
       err.message &&
       err.message.includes('write error (disk full?)')
     ) {
-      throw new Error('disk-space');
+      throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE);
     } else {
       logger.debug({ err }, 'Failed to generate composer.lock');
     }
diff --git a/lib/manager/gradle/index.ts b/lib/manager/gradle/index.ts
index c5807d02551976e12bec7a3ccbd2e3f9a526afab..334f294242133436b1c962d69c49f5e909536af2 100644
--- a/lib/manager/gradle/index.ts
+++ b/lib/manager/gradle/index.ts
@@ -3,6 +3,7 @@ import upath from 'upath';
 
 import { exec } from '../../util/exec';
 import { logger } from '../../logger';
+import { DATASOURCE_FAILURE } from '../../constants/error-messages';
 
 import {
   init,
@@ -87,7 +88,7 @@ async function executeGradle(
     }
     logger.warn({ err, cmd }, 'Gradle run failed');
     logger.info('Aborting Renovate due to Gradle lookup errors');
-    throw new Error('registry-failure');
+    throw new Error(DATASOURCE_FAILURE);
   }
   logger.debug(stdout + stderr);
   logger.info('Gradle report complete');
diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts
index 72b3d68de6830da1fd1007a8fbc988fac6d60151..ef0352bc7dfe6a856f339f2c5891a95bca2e577c 100644
--- a/lib/manager/npm/extract/index.ts
+++ b/lib/manager/npm/extract/index.ts
@@ -16,6 +16,7 @@ import {
 } from '../../common';
 import { NpmPackage } from './common';
 import { platform } from '../../../platform';
+import { CONFIG_VALIDATION } from '../../../constants/error-messages';
 
 export async function extractPackageFile(
   content: string,
@@ -38,7 +39,7 @@ export async function extractPackageFile(
     return null;
   }
   if (fileName !== 'package.json' && packageJson.renovate) {
-    const error = new Error('config-validation');
+    const error = new Error(CONFIG_VALIDATION);
     error.configFile = fileName;
     error.validationError =
       'Nested package.json must not contain renovate configuration. Please use `packageRules` with `paths` in your main config instead.';
diff --git a/lib/manager/npm/post-update/index.ts b/lib/manager/npm/post-update/index.ts
index 0a615c2e71184094ecc3962a3ba605f7e1ce95dd..fe48b52a463ce0b512d46be691a97b29fdf45719 100644
--- a/lib/manager/npm/post-update/index.ts
+++ b/lib/manager/npm/post-update/index.ts
@@ -11,6 +11,10 @@ import * as hostRules from '../../../util/host-rules';
 import { getChildProcessEnv } from '../../../util/exec/env';
 import { PostUpdateConfig, PackageFile, Upgrade } from '../../common';
 import { platform } from '../../../platform';
+import {
+  SYSTEM_INSUFFICIENT_DISK_SPACE,
+  DATASOURCE_FAILURE,
+} from '../../../constants/error-messages';
 
 // Strips empty values, deduplicates, and returns the directories from filenames
 // istanbul ignore next
@@ -381,7 +385,7 @@ export async function getAdditionalFiles(
               { dependency: upgrade.depName, type: 'npm' },
               'lock file failed for the dependency being updated - skipping branch creation'
             );
-            throw new Error('registry-failure');
+            throw new Error(DATASOURCE_FAILURE);
           }
         }
       }
@@ -433,7 +437,7 @@ export async function getAdditionalFiles(
               { dependency: upgrade.depName, type: 'yarn' },
               'lock file failed for the dependency being updated - skipping branch creation'
             );
-            throw new Error('registry-failure');
+            throw new Error(DATASOURCE_FAILURE);
           }
           /* eslint-enable no-useless-escape */
         }
@@ -519,7 +523,7 @@ export async function getAdditionalFiles(
               { dependency: upgrade.depName, type: 'pnpm' },
               'lock file failed for the dependency being updated - skipping branch creation'
             );
-            throw new Error('registry-failure');
+            throw new Error(DATASOURCE_FAILURE);
           }
         }
       }
@@ -575,7 +579,7 @@ export async function getAdditionalFiles(
         res.stderr &&
         res.stderr.includes('ENOSPC: no space left on device')
       ) {
-        throw new Error('disk-space');
+        throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE);
       }
       for (const upgrade of config.upgrades) {
         /* eslint-disable no-useless-escape */
@@ -588,7 +592,7 @@ export async function getAdditionalFiles(
             { dependency: upgrade.depName, type: 'yarn' },
             'lock file failed for the dependency being updated - skipping branch creation'
           );
-          throw new Error('registry-failure');
+          throw new Error(DATASOURCE_FAILURE);
         }
         /* eslint-enable no-useless-escape */
         if (
@@ -600,7 +604,7 @@ export async function getAdditionalFiles(
             { dependency: upgrade.depName, type: 'npm' },
             'lock file failed for the dependency being updated - skipping branch creation'
           );
-          throw new Error('registry-failure');
+          throw new Error(DATASOURCE_FAILURE);
         }
       }
       artifactErrors.push({
diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts
index f6cc933d5e4fa85405698abbeb55576eb2084e54..248d9f6d84b42a3be9fd1c4f96248e4cb01000ef 100644
--- a/lib/manager/npm/post-update/npm.ts
+++ b/lib/manager/npm/post-update/npm.ts
@@ -4,6 +4,7 @@ import { getInstalledPath } from 'get-installed-path';
 import { exec } from '../../../util/exec';
 import { logger } from '../../../logger';
 import { PostUpdateConfig, Upgrade } from '../../common';
+import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../../constants/error-messages';
 
 export interface GenerateLockFileResult {
   error?: boolean;
@@ -135,7 +136,7 @@ export async function generateLockFile(
     }
     // istanbul ignore if
     if (stderr && stderr.includes('ENOSPC: no space left on device')) {
-      throw new Error('disk-space');
+      throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE);
     }
     const duration = process.hrtime(startTime);
     const seconds = Math.round(duration[0] + duration[1] / 1e9);
diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts
index 3c48a995a26a8b333dcc7b491b2f86197c6ace4c..9c5b0a9a5cfb5f7009c724081de65099655fa5d6 100644
--- a/lib/manager/npm/post-update/yarn.ts
+++ b/lib/manager/npm/post-update/yarn.ts
@@ -4,6 +4,10 @@ import { getInstalledPath } from 'get-installed-path';
 import { exec } from '../../../util/exec';
 import { logger } from '../../../logger';
 import { PostUpdateConfig, Upgrade } from '../../common';
+import {
+  SYSTEM_INSUFFICIENT_DISK_SPACE,
+  DATASOURCE_FAILURE,
+} from '../../../constants/error-messages';
 
 export interface GenerateLockFileResult {
   error?: boolean;
@@ -176,14 +180,14 @@ export async function generateLockFile(
     );
     if (err.stderr) {
       if (err.stderr.includes('ENOSPC: no space left on device')) {
-        throw new Error('disk-space');
+        throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE);
       }
       if (
         err.stderr.includes('The registry may be down.') ||
         err.stderr.includes('getaddrinfo ENOTFOUND registry.yarnpkg.com') ||
         err.stderr.includes('getaddrinfo ENOTFOUND registry.npmjs.org')
       ) {
-        throw new Error('registry-failure');
+        throw new Error(DATASOURCE_FAILURE);
       }
     }
     return { error: true, stderr: err.stderr };
diff --git a/lib/platform/azure/index.ts b/lib/platform/azure/index.ts
index efbe7292974db7aa14ef4c09f19c9471bbe9f778..95b3ead1a948041ac5e18d75c1c052b138b6caeb 100644
--- a/lib/platform/azure/index.ts
+++ b/lib/platform/azure/index.ts
@@ -20,6 +20,7 @@ import {
 } from '../common';
 import { sanitize } from '../../util/sanitize';
 import { smartTruncate } from '../utils/pr-body';
+import { REPOSITORY_DISABLED } from '../../constants/error-messages';
 
 interface Config {
   storage: GitStorage;
@@ -129,7 +130,7 @@ export async function initRepo({
       // Do nothing
     }
     if (renovateConfig && renovateConfig.enabled === false) {
-      throw new Error('disabled');
+      throw new Error(REPOSITORY_DISABLED);
     }
   }
 
diff --git a/lib/platform/bitbucket-server/index.ts b/lib/platform/bitbucket-server/index.ts
index 729aa03ee707d292d9c1b8d948ca0dbbcad42b10..c534bc2404d36b11c6824f196e201a42064ba08a 100644
--- a/lib/platform/bitbucket-server/index.ts
+++ b/lib/platform/bitbucket-server/index.ts
@@ -19,7 +19,11 @@ import {
 } from '../common';
 import { sanitize } from '../../util/sanitize';
 import { smartTruncate } from '../utils/pr-body';
-
+import {
+  REPOSITORY_CHANGED,
+  REPOSITORY_DISABLED,
+  REPOSITORY_NOT_FOUND,
+} from '../../constants/error-messages';
 /*
  * Version: 5.3 (EOL Date: 15 Aug 2019)
  * See following docs for api information:
@@ -156,7 +160,7 @@ export async function initRepo({
       // Do nothing
     }
     if (renovateConfig && renovateConfig.enabled === false) {
-      throw new Error('disabled');
+      throw new Error(REPOSITORY_DISABLED);
     }
   }
 
@@ -211,7 +215,7 @@ export async function initRepo({
   } catch (err) /* istanbul ignore next */ {
     logger.debug(err);
     if (err.statusCode === 404) {
-      throw new Error('not-found');
+      throw new Error(REPOSITORY_NOT_FOUND);
     }
     logger.info({ err }, 'Unknown Bitbucket initRepo error');
     throw err;
@@ -514,7 +518,7 @@ export async function getBranchStatus(
   }
 
   if (!(await branchExists(branchName))) {
-    throw new Error('repository-changed');
+    throw new Error(REPOSITORY_CHANGED);
   }
 
   try {
@@ -683,7 +687,7 @@ export async function addReviewers(
   try {
     const pr = await getPr(prNo);
     if (!pr) {
-      throw Object.assign(new Error('not-found'), { statusCode: 404 });
+      throw new Error(REPOSITORY_NOT_FOUND);
     }
 
     const reviewersSet = new Set([...pr.reviewers, ...reviewers]);
@@ -702,9 +706,9 @@ export async function addReviewers(
     await getPr(prNo, true);
   } catch (err) {
     if (err.statusCode === 404) {
-      throw new Error('not-found');
+      throw new Error(REPOSITORY_NOT_FOUND);
     } else if (err.statusCode === 409) {
-      throw new Error('repository-changed');
+      throw new Error(REPOSITORY_CHANGED);
     } else {
       logger.fatal({ err }, `Failed to add reviewers ${reviewers} to #${prNo}`);
       throw err;
@@ -921,7 +925,7 @@ export async function createPr({
         'Empty pull request - deleting branch so it can be recreated next run'
       );
       await deleteBranch(branchName);
-      throw new Error('repository-changed');
+      throw new Error(REPOSITORY_CHANGED);
     }
     throw err;
   }
@@ -969,7 +973,7 @@ export async function updatePr(
   try {
     const pr = await getPr(prNo);
     if (!pr) {
-      throw Object.assign(new Error('not-found'), { statusCode: 404 });
+      throw Object.assign(new Error(REPOSITORY_NOT_FOUND), { statusCode: 404 });
     }
 
     const { body } = await api.put<{ version: number }>(
@@ -987,9 +991,9 @@ export async function updatePr(
     updatePrVersion(prNo, body.version);
   } catch (err) {
     if (err.statusCode === 404) {
-      throw new Error('not-found');
+      throw new Error(REPOSITORY_NOT_FOUND);
     } else if (err.statusCode === 409) {
-      throw new Error('repository-changed');
+      throw new Error(REPOSITORY_CHANGED);
     } else {
       logger.fatal({ err }, `Failed to update PR`);
       throw err;
@@ -1007,7 +1011,7 @@ export async function mergePr(
   try {
     const pr = await getPr(prNo);
     if (!pr) {
-      throw Object.assign(new Error('not-found'), { statusCode: 404 });
+      throw Object.assign(new Error(REPOSITORY_NOT_FOUND), { statusCode: 404 });
     }
     const { body } = await api.post<{ version: number }>(
       `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/merge?version=${pr.version}`
@@ -1015,7 +1019,7 @@ export async function mergePr(
     updatePrVersion(prNo, body.version);
   } catch (err) {
     if (err.statusCode === 404) {
-      throw new Error('not-found');
+      throw new Error(REPOSITORY_NOT_FOUND);
     } else if (err.statusCode === 409) {
       logger.warn({ err }, `Failed to merge PR`);
       return false;
diff --git a/lib/platform/bitbucket/index.ts b/lib/platform/bitbucket/index.ts
index 4c7a5ebb127e658c5c5c6f879fd6340d6b9ed8a0..2411c79fa956a1e999f01398436109b54b36b75f 100644
--- a/lib/platform/bitbucket/index.ts
+++ b/lib/platform/bitbucket/index.ts
@@ -20,6 +20,10 @@ import {
 } from '../common';
 import { sanitize } from '../../util/sanitize';
 import { smartTruncate } from '../utils/pr-body';
+import {
+  REPOSITORY_DISABLED,
+  REPOSITORY_NOT_FOUND,
+} from '../../constants/error-messages';
 
 let config: utils.Config = {} as any;
 
@@ -100,7 +104,7 @@ export async function initRepo({
         // Do nothing
       }
       if (renovateConfig && renovateConfig.enabled === false) {
-        throw new Error('disabled');
+        throw new Error(REPOSITORY_DISABLED);
       }
     }
 
@@ -115,7 +119,7 @@ export async function initRepo({
     logger.debug(`${repository} owner = ${config.owner}`);
   } catch (err) /* istanbul ignore next */ {
     if (err.statusCode === 404) {
-      throw new Error('not-found');
+      throw new Error(REPOSITORY_NOT_FOUND);
     }
     logger.info({ err }, 'Unknown Bitbucket initRepo error');
     throw err;
diff --git a/lib/platform/git/storage.ts b/lib/platform/git/storage.ts
index 6da8ba661b461ec9e608975195d4504aad35b0d8..62d4b11d3bf74c9b3d3aa5414d2468bff78aabcf 100644
--- a/lib/platform/git/storage.ts
+++ b/lib/platform/git/storage.ts
@@ -5,6 +5,13 @@ import Git from 'simple-git/promise';
 import URL from 'url';
 import { logger } from '../../logger';
 import * as limits from '../../workers/global/limits';
+import {
+  CONFIG_VALIDATION,
+  PLATFORM_FAILURE,
+  REPOSITORY_CHANGED,
+  REPOSITORY_EMPTY,
+  REPOSITORY_TEMPORARY_ERROR,
+} from '../../constants/error-messages';
 
 declare module 'fs-extra' {
   // eslint-disable-next-line import/prefer-default-export
@@ -66,7 +73,7 @@ function checkForPlatformFailure(err: Error): void {
   ];
   for (const errorStr of platformFailureStrings) {
     if (err.message.includes(errorStr)) {
-      throw new Error('platform-failure');
+      throw new Error(PLATFORM_FAILURE);
     }
   }
 }
@@ -76,7 +83,7 @@ function localName(branchName: string): string {
 }
 
 function throwBaseBranchValidationError(branchName: string): never {
-  const error = new Error('config-validation');
+  const error = new Error(CONFIG_VALIDATION);
   error.validationError = 'baseBranch not found';
   error.validationMessage =
     'The following configured baseBranch could not be found: ' + branchName;
@@ -145,7 +152,7 @@ export class Storage {
             'fatal: ref refs/remotes/origin/HEAD is not a symbolic ref'
           )
         ) {
-          throw new Error('empty');
+          throw new Error(REPOSITORY_EMPTY);
         }
         throw err;
       }
@@ -180,7 +187,7 @@ export class Storage {
         await this._git.clone(config.url, '.', ['--depth=2']);
       } catch (err) /* istanbul ignore next */ {
         logger.debug({ err }, 'git clone error');
-        throw new Error('platform-failure');
+        throw new Error(PLATFORM_FAILURE);
       }
       const cloneSeconds =
         Math.round(1 + 10 * convertHrtime(process.hrtime(cloneStart)).seconds) /
@@ -202,7 +209,7 @@ export class Storage {
     } catch (err) /* istanbul ignore next */ {
       checkForPlatformFailure(err);
       if (err.message.includes('does not have any commits yet')) {
-        throw new Error('empty');
+        throw new Error(REPOSITORY_EMPTY);
       }
       logger.warn({ err }, 'Cannot retrieve latest commit date');
     }
@@ -222,7 +229,7 @@ export class Storage {
       } catch (err) /* istanbul ignore next */ {
         checkForPlatformFailure(err);
         logger.debug({ err }, 'Error setting git config');
-        throw new Error('temporary-error');
+        throw new Error(REPOSITORY_TEMPORARY_ERROR);
       }
     }
 
@@ -455,7 +462,7 @@ export class Storage {
       const exists = await this.branchExists(branchName);
       if (!exists) {
         logger.info({ branchName }, 'branch no longer exists - aborting');
-        throw new Error('repository-changed');
+        throw new Error(REPOSITORY_CHANGED);
       }
     }
     try {
@@ -525,7 +532,7 @@ export class Storage {
     } catch (err) /* istanbul ignore next */ {
       checkForPlatformFailure(err);
       logger.debug({ err }, 'Error commiting files');
-      throw new Error('repository-changed');
+      throw new Error(REPOSITORY_CHANGED);
     }
   }
 
diff --git a/lib/platform/github/gh-got-wrapper.ts b/lib/platform/github/gh-got-wrapper.ts
index ff1e9bc20f375e8f5632574003b82225dc66ad51..5a91dfe9792dfadab8fa4dfaa4271de9e8a92c47 100644
--- a/lib/platform/github/gh-got-wrapper.ts
+++ b/lib/platform/github/gh-got-wrapper.ts
@@ -7,6 +7,13 @@ import got, { GotJSONOptions } from '../../util/got';
 import { maskToken } from '../../util/mask';
 import { GotApi, GotResponse } from '../common';
 import { logger } from '../../logger';
+import {
+  PLATFORM_BAD_CREDENTIALS,
+  PLATFORM_INTEGRATION_UNAUTHORIZED,
+  PLATFORM_FAILURE,
+  PLATFORM_RATE_LIMIT_EXCEEDED,
+  REPOSITORY_CHANGED,
+} from '../../constants/error-messages';
 
 const hostType = 'github';
 export const getHostType = (): string => hostType;
@@ -42,22 +49,22 @@ export function dispatchError(
       err.code === 'EAI_AGAIN')
   ) {
     logger.info({ err }, 'GitHub failure: RequestError');
-    throw new Error('platform-failure');
+    throw new Error(PLATFORM_FAILURE);
   }
   if (err.name === 'ParseError') {
     logger.info({ err }, 'GitHub failure: ParseError');
-    throw new Error('platform-failure');
+    throw new Error(PLATFORM_FAILURE);
   }
   if (err.statusCode >= 500 && err.statusCode < 600) {
     logger.info({ err }, 'GitHub failure: 5xx');
-    throw new Error('platform-failure');
+    throw new Error(PLATFORM_FAILURE);
   }
   if (
     err.statusCode === 403 &&
     message.startsWith('You have triggered an abuse detection mechanism')
   ) {
     logger.info({ err }, 'GitHub failure: abuse detection');
-    throw new Error('platform-failure');
+    throw new Error(PLATFORM_RATE_LIMIT_EXCEEDED);
   }
   if (err.statusCode === 403 && message.includes('Upgrade to GitHub Pro')) {
     logger.debug({ path }, 'Endpoint needs paid GitHub plan');
@@ -65,7 +72,7 @@ export function dispatchError(
   }
   if (err.statusCode === 403 && message.includes('rate limit exceeded')) {
     logger.info({ err }, 'GitHub failure: rate limit');
-    throw new Error('rate-limit-exceeded');
+    throw new Error(PLATFORM_RATE_LIMIT_EXCEEDED);
   }
   if (
     err.statusCode === 403 &&
@@ -75,7 +82,7 @@ export function dispatchError(
       { err },
       'GitHub failure: Resource not accessible by integration'
     );
-    throw new Error('integration-unauthorized');
+    throw new Error(PLATFORM_INTEGRATION_UNAUTHORIZED);
   }
   if (err.statusCode === 401 && message.includes('Bad credentials')) {
     const rateLimit = err.headers ? err.headers['x-ratelimit-limit'] : -1;
@@ -87,9 +94,9 @@ export function dispatchError(
       'GitHub failure: Bad credentials'
     );
     if (rateLimit === '60') {
-      throw new Error('platform-failure');
+      throw new Error(PLATFORM_FAILURE);
     }
-    throw new Error('bad-credentials');
+    throw new Error(PLATFORM_BAD_CREDENTIALS);
   }
   if (err.statusCode === 422) {
     if (
@@ -101,9 +108,9 @@ export function dispatchError(
       err.body.errors &&
       err.body.errors.find((e: any) => e.code === 'invalid')
     ) {
-      throw new Error('repository-changed');
+      throw new Error(REPOSITORY_CHANGED);
     }
-    throw new Error('platform-failure');
+    throw new Error(PLATFORM_FAILURE);
   }
   throw err;
 }
diff --git a/lib/platform/github/index.ts b/lib/platform/github/index.ts
index 9b762cf19032cc7fef34683562a884a221865982..372b3d40582119b82791f8fce141b9bb7725b43c 100644
--- a/lib/platform/github/index.ts
+++ b/lib/platform/github/index.ts
@@ -22,6 +22,19 @@ import { configFileNames } from '../../config/app-strings';
 import { sanitize } from '../../util/sanitize';
 import { smartTruncate } from '../utils/pr-body';
 import { getGraphqlNodes } from './gh-graphql-wrapper';
+import {
+  PLATFORM_FAILURE,
+  REPOSITORY_ACCESS_FORBIDDEN,
+  REPOSITORY_ARCHIVED,
+  REPOSITORY_BLOCKED,
+  REPOSITORY_CANNOT_FORK,
+  REPOSITORY_CHANGED,
+  REPOSITORY_DISABLED,
+  REPOSITORY_EMPTY,
+  REPOSITORY_FORKED,
+  REPOSITORY_NOT_FOUND,
+  REPOSITORY_RENAMED,
+} from '../../constants/error-messages';
 
 const defaultConfigFile = configFileNames[0];
 
@@ -183,10 +196,10 @@ async function getBranchCommit(branchName: string): Promise<string> {
   } catch (err) /* istanbul ignore next */ {
     logger.debug({ err }, 'Error getting branch commit');
     if (err.statusCode === 404) {
-      throw new Error('repository-changed');
+      throw new Error(REPOSITORY_CHANGED);
     }
     if (err.statusCode === 409) {
-      throw new Error('empty');
+      throw new Error(REPOSITORY_EMPTY);
     }
     throw err;
   }
@@ -252,7 +265,7 @@ export async function initRepo({
           throw new Error();
         }
       } catch (err) {
-        throw new Error('fork');
+        throw new Error(REPOSITORY_FORKED);
       }
     }
     if (res.body.full_name && res.body.full_name !== repository) {
@@ -260,13 +273,13 @@ export async function initRepo({
         { repository, this_repository: res.body.full_name },
         'Repository has been renamed'
       );
-      throw new Error('renamed');
+      throw new Error(REPOSITORY_RENAMED);
     }
     if (res.body.archived) {
       logger.info(
         'Repository is archived - throwing error to abort renovation'
       );
-      throw new Error('archived');
+      throw new Error(REPOSITORY_ARCHIVED);
     }
     if (optimizeForDisabled) {
       let renovateConfig;
@@ -283,7 +296,7 @@ export async function initRepo({
         // Do nothing
       }
       if (renovateConfig && renovateConfig.enabled === false) {
-        throw new Error('disabled');
+        throw new Error(REPOSITORY_DISABLED);
       }
     }
     const owner = res.body.owner.login;
@@ -306,26 +319,29 @@ export async function initRepo({
     }
   } catch (err) /* istanbul ignore next */ {
     logger.debug('Caught initRepo error');
-    if (err.message === 'archived' || err.message === 'renamed') {
+    if (
+      err.message === REPOSITORY_ARCHIVED ||
+      err.message === REPOSITORY_RENAMED
+    ) {
       throw err;
     }
     if (err.statusCode === 403) {
-      throw new Error('forbidden');
+      throw new Error(REPOSITORY_ACCESS_FORBIDDEN);
     }
     if (err.statusCode === 404) {
-      throw new Error('not-found');
+      throw new Error(REPOSITORY_NOT_FOUND);
     }
     if (err.message.startsWith('Repository access blocked')) {
-      throw new Error('blocked');
+      throw new Error(REPOSITORY_BLOCKED);
     }
-    if (err.message === 'fork') {
+    if (err.message === REPOSITORY_FORKED) {
       throw err;
     }
-    if (err.message === 'disabled') {
+    if (err.message === REPOSITORY_DISABLED) {
       throw err;
     }
     if (err.message === 'Response code 451 (Unavailable for Legal Reasons)') {
-      throw new Error('forbidden');
+      throw new Error(REPOSITORY_ACCESS_FORBIDDEN);
     }
     logger.info({ err }, 'Unknown GitHub initRepo error');
     throw err;
@@ -358,7 +374,7 @@ export async function initRepo({
       })).body.full_name;
     } catch (err) /* istanbul ignore next */ {
       logger.info({ err }, 'Error forking repository');
-      throw new Error('cannot-fork');
+      throw new Error(REPOSITORY_CANNOT_FORK);
     }
     if (existingRepos.includes(config.repository!)) {
       logger.info(
@@ -384,14 +400,14 @@ export async function initRepo({
           }
         );
       } catch (err) /* istanbul ignore next */ {
-        if (err.message === 'platform-failure') {
+        if (err.message === PLATFORM_FAILURE) {
           throw err;
         }
         if (
           err.statusCode === 422 &&
           err.message.startsWith('Object does not exist')
         ) {
-          throw new Error('repository-changed');
+          throw new Error(REPOSITORY_CHANGED);
         }
       }
     } else {
@@ -1037,7 +1053,7 @@ export async function getBranchStatus(
       logger.info(
         'Received 404 when checking branch status, assuming that branch has been deleted'
       );
-      throw new Error('repository-changed');
+      throw new Error(REPOSITORY_CHANGED);
     }
     logger.info('Unknown error when checking branch status');
     throw err;
@@ -1129,7 +1145,7 @@ export async function getBranchStatusCheck(
   } catch (err) /* istanbul ignore next */ {
     if (err.statusCode === 404) {
       logger.info('Commit not found when checking statuses');
-      throw new Error('repository-changed');
+      throw new Error(REPOSITORY_CHANGED);
     }
     throw err;
   }
@@ -1170,7 +1186,7 @@ export async function setBranchStatus({
     await getStatusCheck(branchName, false);
   } catch (err) /* istanbul ignore next */ {
     logger.info({ err }, 'Caught error setting branch status - aborting');
-    throw new Error('repository-changed');
+    throw new Error(REPOSITORY_CHANGED);
   }
 }
 
@@ -1478,7 +1494,7 @@ async function getComments(issueNo: number): Promise<Comment[]> {
   } catch (err) /* istanbul ignore next */ {
     if (err.statusCode === 404) {
       logger.debug('404 respose when retrieving comments');
-      throw new Error('platform-failure');
+      throw new Error(PLATFORM_FAILURE);
     }
     throw err;
   }
diff --git a/lib/platform/gitlab/gl-got-wrapper.ts b/lib/platform/gitlab/gl-got-wrapper.ts
index 3488dcdb9df071c127ea665ccab85946cd781efb..5ac54d14bc5fc16c65b33a7abbfe2dca2955c9d3 100644
--- a/lib/platform/gitlab/gl-got-wrapper.ts
+++ b/lib/platform/gitlab/gl-got-wrapper.ts
@@ -3,6 +3,7 @@ import parseLinkHeader from 'parse-link-header';
 import { GotApi, GotResponse } from '../common';
 import got from '../../util/got';
 import { logger } from '../../logger';
+import { PLATFORM_FAILURE } from '../../constants/error-messages';
 
 const hostType = 'gitlab';
 let baseUrl = 'https://gitlab.com/api/v4/';
@@ -32,7 +33,7 @@ async function get(path: string, options: any): Promise<GotResponse> {
     return res;
   } catch (err) /* istanbul ignore next */ {
     if (err.statusCode >= 500 && err.statusCode < 600) {
-      throw new Error('platform-failure');
+      throw new Error(PLATFORM_FAILURE);
     }
     const platformFailureCodes = [
       'EAI_AGAIN',
@@ -41,7 +42,7 @@ async function get(path: string, options: any): Promise<GotResponse> {
       'UNABLE_TO_VERIFY_LEAF_SIGNATURE',
     ];
     if (platformFailureCodes.includes(err.code)) {
-      throw new Error('platform-failure');
+      throw new Error(PLATFORM_FAILURE);
     }
     throw err;
   }
diff --git a/lib/platform/gitlab/index.ts b/lib/platform/gitlab/index.ts
index b04600874c8a0934c04d41858c6febb12103ccbe..b10c7edf5d605f5908d51de565babc87f68ec2dc 100644
--- a/lib/platform/gitlab/index.ts
+++ b/lib/platform/gitlab/index.ts
@@ -21,6 +21,16 @@ import { logger } from '../../logger';
 import { sanitize } from '../../util/sanitize';
 import { smartTruncate } from '../utils/pr-body';
 import { RenovateConfig } from '../../config';
+import {
+  PLATFORM_AUTHENTICATION_ERROR,
+  REPOSITORY_ACCESS_FORBIDDEN,
+  REPOSITORY_ARCHIVED,
+  REPOSITORY_CHANGED,
+  REPOSITORY_DISABLED,
+  REPOSITORY_EMPTY,
+  REPOSITORY_MIRRORED,
+  REPOSITORY_NOT_FOUND,
+} from '../../constants/error-messages';
 
 const defaultConfigFile = configFileNames[0];
 let config: {
@@ -134,28 +144,28 @@ export async function initRepo({
       logger.info(
         'Repository is archived - throwing error to abort renovation'
       );
-      throw new Error('archived');
+      throw new Error(REPOSITORY_ARCHIVED);
     }
     if (res.body.mirror) {
       logger.info(
         'Repository is a mirror - throwing error to abort renovation'
       );
-      throw new Error('mirror');
+      throw new Error(REPOSITORY_MIRRORED);
     }
     if (res.body.repository_access_level === 'disabled') {
       logger.info(
         'Repository portion of project is disabled - throwing error to abort renovation'
       );
-      throw new Error('disabled');
+      throw new Error(REPOSITORY_DISABLED);
     }
     if (res.body.merge_requests_access_level === 'disabled') {
       logger.info(
         'MRs are disabled for the project - throwing error to abort renovation'
       );
-      throw new Error('disabled');
+      throw new Error(REPOSITORY_DISABLED);
     }
     if (res.body.default_branch === null || res.body.empty_repo) {
-      throw new Error('empty');
+      throw new Error(REPOSITORY_EMPTY);
     }
     if (optimizeForDisabled) {
       let renovateConfig: RenovateConfig;
@@ -172,7 +182,7 @@ export async function initRepo({
         // Do nothing
       }
       if (renovateConfig && renovateConfig.enabled === false) {
-        throw new Error('disabled');
+        throw new Error(REPOSITORY_DISABLED);
       }
     }
     config.defaultBranch = res.body.default_branch;
@@ -211,18 +221,18 @@ export async function initRepo({
   } catch (err) /* istanbul ignore next */ {
     logger.debug({ err }, 'Caught initRepo error');
     if (err.message.includes('HEAD is not a symbolic ref')) {
-      throw new Error('empty');
+      throw new Error(REPOSITORY_EMPTY);
     }
     if (['archived', 'empty'].includes(err.message)) {
       throw err;
     }
     if (err.statusCode === 403) {
-      throw new Error('forbidden');
+      throw new Error(REPOSITORY_ACCESS_FORBIDDEN);
     }
     if (err.statusCode === 404) {
-      throw new Error('not-found');
+      throw new Error(REPOSITORY_NOT_FOUND);
     }
-    if (err.message === 'disabled') {
+    if (err.message === REPOSITORY_DISABLED) {
       throw err;
     }
     logger.info({ err }, 'Unknown GitLab initRepo error');
@@ -300,7 +310,7 @@ export async function getBranchStatus(
   }
 
   if (!(await branchExists(branchName))) {
-    throw new Error('repository-changed');
+    throw new Error(REPOSITORY_CHANGED);
   }
 
   const res = await getStatus(branchName);
@@ -919,7 +929,7 @@ async function fetchPrList(): Promise<Pr[]> {
   } catch (err) /* istanbul ignore next */ {
     logger.debug({ err }, 'Error fetching PR list');
     if (err.statusCode === 403) {
-      throw new Error('authentication-error');
+      throw new Error(PLATFORM_AUTHENTICATION_ERROR);
     }
     throw err;
   }
diff --git a/lib/platform/index.ts b/lib/platform/index.ts
index 7d335490f0bd3e8a5346cec937a2564fcab6abd5..c9d0715eace26174b7bcf6d252d9fe38dd3117b2 100644
--- a/lib/platform/index.ts
+++ b/lib/platform/index.ts
@@ -5,6 +5,7 @@ import { logger } from '../logger';
 import { Platform } from './common';
 import { RenovateConfig } from '../config/common';
 import { getOptions } from '../config/definitions';
+import { PLATFORM_NOT_FOUND } from '../constants/error-messages';
 
 export * from './common';
 
@@ -16,7 +17,7 @@ let _platform: Platform;
 
 const handler: ProxyHandler<Platform> = {
   get(_target: Platform, prop: keyof Platform) {
-    if (!_platform) throw new Error(`platform-not-found`);
+    if (!_platform) throw new Error(PLATFORM_NOT_FOUND);
 
     // TODO: add more validation
 
diff --git a/lib/util/regex.ts b/lib/util/regex.ts
index 41dfce98f1ba292eaa95bf964c1bbefb3da29564..7cc415c653ae2fa54b3acffe30e5b2690f740232 100644
--- a/lib/util/regex.ts
+++ b/lib/util/regex.ts
@@ -1,4 +1,5 @@
 import { logger } from '../logger';
+import { CONFIG_VALIDATION } from '../constants/error-messages';
 
 let RegEx;
 
@@ -18,7 +19,7 @@ export function regEx(pattern: string, flags?: string): RegExp {
   try {
     return new RegEx(pattern, flags);
   } catch (err) {
-    const error = new Error('config-validation');
+    const error = new Error(CONFIG_VALIDATION);
     error.configFile = pattern;
     error.validationError = 'Invalid regular expression: ' + err.toString();
     throw error;
diff --git a/lib/versioning/regex/index.ts b/lib/versioning/regex/index.ts
index 810ff33d581ff5fdbac312d520f2bee027598ae1..9a4a6f788216350a87f1c357a6f5b8953904ebce 100644
--- a/lib/versioning/regex/index.ts
+++ b/lib/versioning/regex/index.ts
@@ -2,6 +2,7 @@ import { compare, satisfies, ltr, minSatisfying, maxSatisfying } from 'semver';
 import { VersioningApiConstructor } from '../common';
 import { GenericVersion, GenericVersioningApi } from '../loose/generic';
 import { regEx } from '../../util/regex';
+import { CONFIG_VALIDATION } from '../../constants/error-messages';
 
 export interface RegExpVersion extends GenericVersion {
   /** prereleases are treated in the standard semver manner, if present */
@@ -47,7 +48,7 @@ export class RegExpVersioningApi extends GenericVersioningApi<RegExpVersion> {
       !new_config.includes('<minor>') &&
       !new_config.includes('<patch>')
     ) {
-      const error = new Error('config-validation');
+      const error = new Error(CONFIG_VALIDATION);
       error.configFile = new_config;
       error.validationError =
         'regex versionScheme needs at least one major, minor or patch group defined';
diff --git a/lib/workers/branch/check-existing.ts b/lib/workers/branch/check-existing.ts
index ece64e7a7ef886dcc159b884e3c4390a3ff78c12..8badbb1e413c448486418643d0061c8c8fdaea06 100644
--- a/lib/workers/branch/check-existing.ts
+++ b/lib/workers/branch/check-existing.ts
@@ -1,6 +1,7 @@
 import { logger } from '../../logger';
 import { RenovateConfig } from '../../config';
 import { platform } from '../../platform';
+import { REPOSITORY_CHANGED } from '../../constants/error-messages';
 
 /** TODO: Proper return type */
 export async function prAlreadyExisted(
@@ -20,7 +21,7 @@ export async function prAlreadyExisted(
     // istanbul ignore if
     if (prDetails.state === 'open') {
       logger.debug('PR reopened');
-      throw new Error('repository-changed');
+      throw new Error(REPOSITORY_CHANGED);
     }
     return pr;
   }
diff --git a/lib/workers/branch/get-updated.ts b/lib/workers/branch/get-updated.ts
index 3176cb84fd25b793b71eb91632df168eb6713ebd..a9e460ac3cceb469c373bb9783e78d7f9ad5a6fe 100644
--- a/lib/workers/branch/get-updated.ts
+++ b/lib/workers/branch/get-updated.ts
@@ -4,6 +4,7 @@ import { logger } from '../../logger';
 import { get } from '../../manager';
 import { RenovateConfig } from '../../config';
 import { UpdateArtifactsConfig, ArtifactError } from '../../manager/common';
+import { WORKER_FILE_UPDATE_FAILED } from '../../constants/error-messages';
 
 export interface PackageFilesResult {
   artifactErrors: ArtifactError[];
@@ -56,7 +57,7 @@ export async function getUpdatedPackageFiles(
           { existingContent, config: upgrade },
           'Error updating file'
         );
-        throw new Error('update-failure');
+        throw new Error(WORKER_FILE_UPDATE_FAILED);
       }
       if (newContent !== existingContent) {
         if (config.parentBranch) {
diff --git a/lib/workers/branch/index.ts b/lib/workers/branch/index.ts
index f66bdfac916bfcf2fb0dd86cb478901bd6951035..4929c1771be5f85cc8b356e4e7d6c398347d4b13 100644
--- a/lib/workers/branch/index.ts
+++ b/lib/workers/branch/index.ts
@@ -17,6 +17,18 @@ import { RenovateConfig } from '../../config';
 import { platform } from '../../platform';
 import { emojify } from '../../util/emoji';
 import { BranchConfig } from '../common';
+import {
+  PLATFORM_AUTHENTICATION_ERROR,
+  PLATFORM_BAD_CREDENTIALS,
+  SYSTEM_INSUFFICIENT_DISK_SPACE,
+  PLATFORM_INTEGRATION_UNAUTHORIZED,
+  MANAGER_LOCKFILE_ERROR,
+  PLATFORM_RATE_LIMIT_EXCEEDED,
+  REPOSITORY_CHANGED,
+  WORKER_FILE_UPDATE_FAILED,
+  DATASOURCE_FAILURE,
+  PLATFORM_FAILURE,
+} from '../../constants/error-messages';
 
 export type ProcessBranchResult =
   | 'already-existed'
@@ -146,7 +158,7 @@ export async function processBranch(
           logger.info(
             'PR has been closed or merged since this run started - aborting'
           );
-          throw new Error('repository-changed');
+          throw new Error(REPOSITORY_CHANGED);
         }
         if (
           branchPr.isModified ||
@@ -311,7 +323,7 @@ export async function processBranch(
           );
         } else {
           logger.info('PR is less than a day old - raise error instead of PR');
-          throw new Error('lockfile-error');
+          throw new Error(MANAGER_LOCKFILE_ERROR);
         }
       } else {
         logger.debug('PR has no releaseTimestamp');
@@ -363,13 +375,13 @@ export async function processBranch(
     }
   } catch (err) /* istanbul ignore next */ {
     if (err.statusCode === 404) {
-      throw new Error('repository-changed');
+      throw new Error(REPOSITORY_CHANGED);
     }
-    if (err.message === 'rate-limit-exceeded') {
+    if (err.message === PLATFORM_RATE_LIMIT_EXCEEDED) {
       logger.debug('Passing rate-limit-exceeded error up');
       throw err;
     }
-    if (err.message === 'repository-changed') {
+    if (err.message === REPOSITORY_CHANGED) {
       logger.debug('Passing repository-changed error up');
       throw err;
     }
@@ -378,7 +390,7 @@ export async function processBranch(
       err.message.startsWith('remote: Invalid username or password')
     ) {
       logger.debug('Throwing bad credentials');
-      throw new Error('bad-credentials');
+      throw new Error(PLATFORM_BAD_CREDENTIALS);
     }
     if (
       err.message &&
@@ -387,24 +399,24 @@ export async function processBranch(
       )
     ) {
       logger.debug('Throwing bad credentials');
-      throw new Error('bad-credentials');
+      throw new Error(PLATFORM_BAD_CREDENTIALS);
     }
-    if (err.message === 'bad-credentials') {
+    if (err.message === PLATFORM_BAD_CREDENTIALS) {
       logger.debug('Passing bad-credentials error up');
       throw err;
     }
-    if (err.message === 'integration-unauthorized') {
+    if (err.message === PLATFORM_INTEGRATION_UNAUTHORIZED) {
       logger.debug('Passing integration-unauthorized error up');
       throw err;
     }
-    if (err.message === 'lockfile-error') {
+    if (err.message === MANAGER_LOCKFILE_ERROR) {
       logger.debug('Passing lockfile-error up');
       throw err;
     }
     if (err.message && err.message.includes('space left on device')) {
-      throw new Error('disk-space');
+      throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE);
     }
-    if (err.message.startsWith('disk-space')) {
+    if (err.message === SYSTEM_INSUFFICIENT_DISK_SPACE) {
       logger.debug('Passing disk-space error up');
       throw err;
     }
@@ -412,7 +424,7 @@ export async function processBranch(
       logger.debug('Passing 403 error up');
       throw err;
     }
-    if (err.message === 'update-failure') {
+    if (err.message === WORKER_FILE_UPDATE_FAILED) {
       logger.warn('Error updating branch: update failure');
     } else if (err.message.startsWith('bundler-')) {
       // we have already warned inside the bundler artifacts error handling, so just return
@@ -421,11 +433,11 @@ export async function processBranch(
       err.messagee &&
       err.message.includes('fatal: Authentication failed')
     ) {
-      throw new Error('authentication-failure');
+      throw new Error(PLATFORM_AUTHENTICATION_ERROR);
     } else if (
-      err.message !== 'registry-failure' &&
+      err.message !== DATASOURCE_FAILURE &&
       err.message !== 'disable-gitfs' &&
-      err.message !== 'platform-failure'
+      err.message !== DATASOURCE_FAILURE
     ) {
       logger.error({ err }, `Error updating branch: ${err.message}`);
     }
@@ -535,9 +547,9 @@ export async function processBranch(
   } catch (err) /* istanbul ignore next */ {
     if (
       [
-        'rate-limit-exceeded',
-        'platform-failure',
-        'repository-changed',
+        PLATFORM_RATE_LIMIT_EXCEEDED,
+        PLATFORM_FAILURE,
+        REPOSITORY_CHANGED,
       ].includes(err.message)
     ) {
       logger.debug('Passing PR error up');
diff --git a/lib/workers/pr/index.ts b/lib/workers/pr/index.ts
index 0ab179e0fd7c12ae46d0f7cd3b189c9b7137ecaf..d5fb7d56111b00d9b7976e87d18eb86a3bd8ee40 100644
--- a/lib/workers/pr/index.ts
+++ b/lib/workers/pr/index.ts
@@ -4,6 +4,12 @@ import { getChangeLogJSON } from './changelog';
 import { getPrBody } from './body';
 import { platform, BranchStatus, Pr } from '../../platform';
 import { BranchConfig } from '../common';
+import {
+  PLATFORM_INTEGRATION_UNAUTHORIZED,
+  PLATFORM_FAILURE,
+  PLATFORM_RATE_LIMIT_EXCEEDED,
+  REPOSITORY_CHANGED,
+} from '../../constants/error-messages';
 
 function noWhitespace(input: string): string {
   return input.replace(/\r?\n|\r|\s/g, '');
@@ -378,10 +384,10 @@ export async function ensurePr(
   } catch (err) {
     // istanbul ignore if
     if (
-      err.message === 'repository-changed' ||
-      err.message === 'rate-limit-exceeded' ||
-      err.message === 'platform-failure' ||
-      err.message === 'integration-unauthorized'
+      err.message === REPOSITORY_CHANGED ||
+      err.message === PLATFORM_RATE_LIMIT_EXCEEDED ||
+      err.message === PLATFORM_FAILURE ||
+      err.message === PLATFORM_INTEGRATION_UNAUTHORIZED
     ) {
       logger.debug('Passing error up');
       throw err;
diff --git a/lib/workers/repository/configured.ts b/lib/workers/repository/configured.ts
index 021a262e60b7898d8ed20154e69d19ea9a532e67..201f7f96a9773005386b85fa82d94aac054254c8 100644
--- a/lib/workers/repository/configured.ts
+++ b/lib/workers/repository/configured.ts
@@ -1,10 +1,14 @@
+import {
+  REPOSITORY_DISABLED,
+  REPOSITORY_FORKED,
+} from '../../constants/error-messages';
 import { RenovateConfig } from '../../config';
 
 export function checkIfConfigured(config: RenovateConfig): void {
   if (config.enabled === false) {
-    throw new Error('disabled');
+    throw new Error(REPOSITORY_DISABLED);
   }
   if (config.isFork && !config.includeForks) {
-    throw new Error('fork');
+    throw new Error(REPOSITORY_FORKED);
   }
 }
diff --git a/lib/workers/repository/error.ts b/lib/workers/repository/error.ts
index 5882d7727eacc505f277a82a53713127342eb71e..9b6a24e8d53cecb36dfe361addd3a16e9ffb0068 100644
--- a/lib/workers/repository/error.ts
+++ b/lib/workers/repository/error.ts
@@ -2,125 +2,153 @@ import { logger } from '../../logger';
 import { raiseConfigWarningIssue } from './error-config';
 import { RenovateConfig } from '../../config';
 
+import {
+  CONFIG_VALIDATION,
+  DATASOURCE_FAILURE,
+  MANAGER_LOCKFILE_ERROR,
+  MANAGER_NO_PACKAGE_FILES,
+  PLATFORM_AUTHENTICATION_ERROR,
+  PLATFORM_BAD_CREDENTIALS,
+  PLATFORM_FAILURE,
+  PLATFORM_INTEGRATION_UNAUTHORIZED,
+  PLATFORM_RATE_LIMIT_EXCEEDED,
+  REPOSITORY_ACCESS_FORBIDDEN,
+  REPOSITORY_ARCHIVED,
+  REPOSITORY_BLOCKED,
+  REPOSITORY_CANNOT_FORK,
+  REPOSITORY_CHANGED,
+  REPOSITORY_DISABLED,
+  REPOSITORY_EMPTY,
+  REPOSITORY_FORKED,
+  REPOSITORY_MIRRORED,
+  REPOSITORY_NO_VULNERABILITY,
+  REPOSITORY_NOT_FOUND,
+  REPOSITORY_RENAMED,
+  REPOSITORY_TEMPORARY_ERROR,
+  REPOSITORY_UNINITIATED,
+  SYSTEM_INSUFFICIENT_DISK_SPACE,
+  UNKNOWN_ERROR,
+} from '../../constants/error-messages';
+
 export default async function handleError(
   config: RenovateConfig,
   err: Error
 ): Promise<string> {
-  if (err.message === 'uninitiated') {
+  if (err.message === REPOSITORY_UNINITIATED) {
     logger.info('Repository is uninitiated - skipping');
     delete config.branchList; // eslint-disable-line no-param-reassign
     return err.message;
   }
-  if (err.message === 'empty') {
+  if (err.message === REPOSITORY_EMPTY) {
     logger.info('Repository is empty - skipping');
     delete config.branchList; // eslint-disable-line no-param-reassign
     return err.message;
   }
-  if (err.message === 'disabled') {
+  if (err.message === REPOSITORY_DISABLED) {
     logger.info('Repository is disabled - skipping');
     return err.message;
   }
-  if (err.message === 'archived') {
+  if (err.message === REPOSITORY_ARCHIVED) {
     logger.info('Repository is archived - skipping');
     delete config.branchList; // eslint-disable-line no-param-reassign
     return err.message;
   }
-  if (err.message === 'mirror') {
+  if (err.message === REPOSITORY_MIRRORED) {
     logger.info('Repository is a mirror - skipping');
     delete config.branchList; // eslint-disable-line no-param-reassign
     return err.message;
   }
-  if (err.message === 'renamed') {
+  if (err.message === REPOSITORY_RENAMED) {
     logger.info('Repository has been renamed - skipping');
     delete config.branchList; // eslint-disable-line no-param-reassign
     return err.message;
   }
-  if (err.message === 'blocked') {
+  if (err.message === REPOSITORY_BLOCKED) {
     delete config.branchList; // eslint-disable-line no-param-reassign
     logger.info('Repository is blocked - skipping');
     return err.message;
   }
-  if (err.message === 'forbidden') {
+  if (err.message === REPOSITORY_ACCESS_FORBIDDEN) {
     delete config.branchList; // eslint-disable-line no-param-reassign
     logger.info('Repository is forbidden');
     return err.message;
   }
-  if (err.message === 'not-found') {
+  if (err.message === REPOSITORY_NOT_FOUND) {
     delete config.branchList; // eslint-disable-line no-param-reassign
     logger.error('Repository is not found');
     return err.message;
   }
-  if (err.message === 'fork') {
+  if (err.message === REPOSITORY_FORKED) {
     logger.info('Repository is a fork and not manually configured - skipping');
     return err.message;
   }
-  if (err.message === 'cannot-fork') {
+  if (err.message === REPOSITORY_CANNOT_FORK) {
     logger.info('Cannot fork repository - skipping');
     return err.message;
   }
-  if (err.message === 'no-package-files') {
+  if (err.message === MANAGER_NO_PACKAGE_FILES) {
     logger.info('Repository has no package files - skipping');
     return err.message;
   }
-  if (err.message === 'no-vulnerability-alerts') {
+  if (err.message === REPOSITORY_NO_VULNERABILITY) {
     logger.info('Repository has no vulnerability alerts - skipping');
     return err.message;
   }
-  if (err.message === 'repository-changed') {
+  if (err.message === REPOSITORY_CHANGED) {
     logger.info('Repository has changed during renovation - aborting');
     delete config.branchList; // eslint-disable-line no-param-reassign
     return err.message;
   }
-  if (err.message === 'config-validation') {
+  if (err.message === CONFIG_VALIDATION) {
     delete config.branchList; // eslint-disable-line no-param-reassign
     logger.info({ error: err }, 'Repository has invalid config');
     await raiseConfigWarningIssue(config, err);
     return err.message;
   }
-  if (err.message === 'registry-failure') {
+  if (err.message === DATASOURCE_FAILURE) {
     logger.info('Registry error - skipping');
     delete config.branchList; // eslint-disable-line no-param-reassign
     return err.message;
   }
-  if (err.message === 'platform-failure') {
+  if (err.message === PLATFORM_FAILURE) {
     logger.info('Platform error - skipping');
     delete config.branchList; // eslint-disable-line no-param-reassign
     return err.message;
   }
   if (
     err.message.includes('No space left on device') ||
-    err.message === 'disk-space'
+    err.message === SYSTEM_INSUFFICIENT_DISK_SPACE
   ) {
     logger.error('Disk space error - skipping');
     delete config.branchList; // eslint-disable-line no-param-reassign
     return err.message;
   }
-  if (err.message === 'rate-limit-exceeded') {
+  if (err.message === PLATFORM_RATE_LIMIT_EXCEEDED) {
     logger.warn('Rate limit exceeded - aborting');
     delete config.branchList; // eslint-disable-line no-param-reassign
     return err.message;
   }
-  if (err.message === 'bad-credentials') {
+  if (err.message === PLATFORM_BAD_CREDENTIALS) {
     logger.warn('Bad credentials - aborting');
     delete config.branchList; // eslint-disable-line no-param-reassign
     return err.message;
   }
-  if (err.message === 'integration-unauthorized') {
+  if (err.message === PLATFORM_INTEGRATION_UNAUTHORIZED) {
     logger.warn('Integration unauthorized - aborting');
     delete config.branchList; // eslint-disable-line no-param-reassign
     return err.message;
   }
-  if (err.message === 'authentication-error') {
+  if (err.message === PLATFORM_AUTHENTICATION_ERROR) {
     logger.warn('Authentication error - aborting');
     delete config.branchList; // eslint-disable-line no-param-reassign
     return err.message;
   }
-  if (err.message === 'temporary-error') {
+  if (err.message === REPOSITORY_TEMPORARY_ERROR) {
     logger.info('Temporary error - aborting');
     delete config.branchList; // eslint-disable-line no-param-reassign
     return err.message;
   }
-  if (err.message === 'lockfile-error') {
+  if (err.message === MANAGER_LOCKFILE_ERROR) {
     delete config.branchList; // eslint-disable-line no-param-reassign
     logger.info('Lock file error - aborting');
     delete config.branchList; // eslint-disable-line no-param-reassign
@@ -130,7 +158,7 @@ export default async function handleError(
     logger.warn({ err }, 'Git error - aborting');
     delete config.branchList; // eslint-disable-line no-param-reassign
     // rewrite this error
-    return 'platform-failure';
+    return PLATFORM_FAILURE;
   }
   if (
     err.message.includes('The remote end hung up unexpectedly') ||
@@ -139,11 +167,12 @@ export default async function handleError(
     logger.warn({ err }, 'Git error - aborting');
     delete config.branchList; // eslint-disable-line no-param-reassign
     // rewrite this error
-    return 'platform-failure';
+    return PLATFORM_FAILURE;
   }
   // Swallow this error so that other repositories can be processed
   logger.error({ err }, `Repository has unknown error`);
   // delete branchList to avoid cleaning up branches
   delete config.branchList; // eslint-disable-line no-param-reassign
-  return 'unknown-error';
+  // eslint-disable-next-line no-undef
+  return UNKNOWN_ERROR;
 }
diff --git a/lib/workers/repository/init/config.ts b/lib/workers/repository/init/config.ts
index 06f5422cb90919d4e3cad172369effc85bba63c4..63f85d7919d506d275e827e70966b2a5a48a73a7 100644
--- a/lib/workers/repository/init/config.ts
+++ b/lib/workers/repository/init/config.ts
@@ -12,6 +12,10 @@ import { flattenPackageRules } from './flatten';
 import * as hostRules from '../../../util/host-rules';
 import { configFileNames } from '../../../config/app-strings';
 import { platform } from '../../../platform';
+import {
+  CONFIG_VALIDATION,
+  DATASOURCE_FAILURE,
+} from '../../../constants/error-messages';
 
 // Check for repository config
 export async function mergeRenovateConfig(
@@ -53,7 +57,7 @@ export async function mergeRenovateConfig(
     // istanbul ignore if
     if (renovateConfig === null) {
       logger.warn('Fetching renovate config returns null');
-      throw new Error('registry-failure');
+      throw new Error(DATASOURCE_FAILURE);
     }
     // istanbul ignore if
     if (!renovateConfig.length) {
@@ -70,7 +74,7 @@ export async function mergeRenovateConfig(
           { renovateConfig },
           'Error parsing renovate config renovate.json5'
         );
-        const error = new Error('config-validation');
+        const error = new Error(CONFIG_VALIDATION);
         error.configFile = configFile;
         error.validationError = 'Invalid JSON5 (parsing failed)';
         error.validationMessage = 'JSON5.parse error: ' + err.message;
@@ -83,7 +87,7 @@ export async function mergeRenovateConfig(
         allowDuplicateKeys
       );
       if (jsonValidationError) {
-        const error = new Error('config-validation');
+        const error = new Error(CONFIG_VALIDATION);
         error.configFile = configFile;
         error.validationError = 'Invalid JSON (parsing failed)';
         error.validationMessage = jsonValidationError;
@@ -95,7 +99,7 @@ export async function mergeRenovateConfig(
         allowDuplicateKeys
       );
       if (jsonValidationError) {
-        const error = new Error('config-validation');
+        const error = new Error(CONFIG_VALIDATION);
         error.configFile = configFile;
         error.validationError = 'Duplicate keys in JSON';
         error.validationMessage = JSON.stringify(jsonValidationError);
@@ -105,7 +109,7 @@ export async function mergeRenovateConfig(
         renovateJson = JSON.parse(renovateConfig);
       } catch (err) /* istanbul ignore next */ {
         logger.debug({ renovateConfig }, 'Error parsing renovate config');
-        const error = new Error('config-validation');
+        const error = new Error(CONFIG_VALIDATION);
         error.configFile = configFile;
         error.validationError = 'Invalid JSON (parsing failed)';
         error.validationMessage = 'JSON.parse error: ' + err.message;
@@ -116,7 +120,7 @@ export async function mergeRenovateConfig(
   }
   const migratedConfig = await migrateAndValidate(config, renovateJson);
   if (migratedConfig.errors.length) {
-    const error = new Error('config-validation');
+    const error = new Error(CONFIG_VALIDATION);
     error.configFile = configFile;
     error.validationError =
       'The renovate configuration file contains some invalid settings';
diff --git a/lib/workers/repository/init/vulnerability.ts b/lib/workers/repository/init/vulnerability.ts
index 6ccb90a5860cad558458a6f3180e59363523a5f6..d0555f8472a1c857461880dd146f7409fc68ccf8 100644
--- a/lib/workers/repository/init/vulnerability.ts
+++ b/lib/workers/repository/init/vulnerability.ts
@@ -2,6 +2,7 @@ import { logger } from '../../../logger';
 import * as versioning from '../../../versioning';
 import { platform } from '../../../platform';
 import { RenovateConfig } from '../../../config';
+import { REPOSITORY_NO_VULNERABILITY } from '../../../constants/error-messages';
 
 export async function detectVulnerabilityAlerts(
   input: RenovateConfig
@@ -17,7 +18,7 @@ export async function detectVulnerabilityAlerts(
   if (!alerts.length) {
     logger.debug('No vulnerability alerts found');
     if (input.vulnerabilityAlertsOnly) {
-      throw new Error('no-vulnerability-alerts');
+      throw new Error(REPOSITORY_NO_VULNERABILITY);
     }
     return input;
   }
diff --git a/lib/workers/repository/onboarding/branch/check.ts b/lib/workers/repository/onboarding/branch/check.ts
index 01c69e55f44ce67abb075453745f8f33568a03e2..85b3cf9c4bfde8d2ad14dc0b92ceb0c35a5d6dac 100644
--- a/lib/workers/repository/onboarding/branch/check.ts
+++ b/lib/workers/repository/onboarding/branch/check.ts
@@ -2,6 +2,7 @@ import { logger } from '../../../../logger';
 import { platform } from '../../../../platform';
 import { configFileNames } from '../../../../config/app-strings';
 import { RenovateConfig } from '../../../../config';
+import { REPOSITORY_DISABLED } from '../../../../constants/error-messages';
 
 const findFile = async (fileName: string): Promise<boolean> => {
   logger.debug(`findFile(${fileName})`);
@@ -60,7 +61,7 @@ export const isOnboarded = async (config: RenovateConfig): Promise<boolean> => {
   // If onboarding has been disabled and config files are required then the
   // repository has not been onboarded yet
   if (config.requireConfig && config.onboarding === false) {
-    throw new Error('disabled');
+    throw new Error(REPOSITORY_DISABLED);
   }
 
   const pr = await closedPrExists(config);
@@ -82,7 +83,7 @@ export const isOnboarded = async (config: RenovateConfig): Promise<boolean> => {
       `Renovate is disabled due to lack of config. If you wish to reenable it, you can either (a) commit a config file to your base branch, or (b) rename this closed PR to trigger a replacement onboarding PR.`
     );
   }
-  throw new Error('disabled');
+  throw new Error(REPOSITORY_DISABLED);
 };
 
 export const onboardingPrExists = async (
diff --git a/lib/workers/repository/onboarding/branch/index.ts b/lib/workers/repository/onboarding/branch/index.ts
index b441162f59515da27d8bbeb2f9926182438c15ac..bc49cde7f2c3d93ca1afc95c243b6b1cd5bc6974 100644
--- a/lib/workers/repository/onboarding/branch/index.ts
+++ b/lib/workers/repository/onboarding/branch/index.ts
@@ -5,6 +5,10 @@ import { rebaseOnboardingBranch } from './rebase';
 import { isOnboarded, onboardingPrExists } from './check';
 import { RenovateConfig } from '../../../../config';
 import { platform } from '../../../../platform';
+import {
+  MANAGER_NO_PACKAGE_FILES,
+  REPOSITORY_FORKED,
+} from '../../../../constants/error-messages';
 
 export async function checkOnboardingBranch(
   config: RenovateConfig
@@ -17,7 +21,7 @@ export async function checkOnboardingBranch(
     return { ...config, repoIsOnboarded };
   }
   if (config.isFork && !config.includeForks) {
-    throw new Error('fork');
+    throw new Error(REPOSITORY_FORKED);
   }
   logger.info('Repo is not onboarded');
   if (await onboardingPrExists(config)) {
@@ -26,7 +30,7 @@ export async function checkOnboardingBranch(
   } else {
     logger.debug('Onboarding PR does not exist');
     if (Object.entries(await extractAllDependencies(config)).length === 0) {
-      throw new Error('no-package-files');
+      throw new Error(MANAGER_NO_PACKAGE_FILES);
     }
     logger.info('Need to create onboarding PR');
     await createOnboardingBranch(config);
diff --git a/lib/workers/repository/process/lookup/filter.ts b/lib/workers/repository/process/lookup/filter.ts
index 641d22abb9986a4ddf7581eb8f4ea4363c6b70b4..c83f207f366e7de04540d83ff441fd40b2fddd26 100644
--- a/lib/workers/repository/process/lookup/filter.ts
+++ b/lib/workers/repository/process/lookup/filter.ts
@@ -2,6 +2,7 @@ import * as semver from 'semver';
 import { logger } from '../../../../logger';
 import * as versioning from '../../../../versioning';
 import { Release } from '../../../../datasource';
+import { CONFIG_VALIDATION } from '../../../../constants/error-messages';
 
 export interface FilterConfig {
   allowedVersions?: string;
@@ -66,7 +67,7 @@ export function filterVersions(
         semver.satisfies(semver.coerce(v), allowedVersions)
       );
     } else {
-      const error = new Error('config-validation');
+      const error = new Error(CONFIG_VALIDATION);
       error.configFile = 'config';
       error.validationError = 'Invalid `allowedVersions`';
       error.validationMessage =
diff --git a/lib/workers/repository/result.ts b/lib/workers/repository/result.ts
index 4a90fdeac176c7381986d78e574ebe0bdbd61b93..6db4f9022721f8c4c7ee5ca434511f1f84b5fe4b 100644
--- a/lib/workers/repository/result.ts
+++ b/lib/workers/repository/result.ts
@@ -1,7 +1,19 @@
 import { RenovateConfig } from '../../config';
+import {
+  MANAGER_NO_PACKAGE_FILES,
+  REPOSITORY_ACCESS_FORBIDDEN,
+  REPOSITORY_ARCHIVED,
+  REPOSITORY_BLOCKED,
+  REPOSITORY_CANNOT_FORK,
+  REPOSITORY_DISABLED,
+  REPOSITORY_EMPTY,
+  REPOSITORY_FORKED,
+  REPOSITORY_MIRRORED,
+  REPOSITORY_RENAMED,
+  REPOSITORY_UNINITIATED,
+} from '../../constants/error-messages';
 
 type ProcessStatus = 'disabled' | 'enabled' | 'onboarding' | 'unknown';
-
 export interface ProcessResult {
   res: string;
   status: ProcessStatus;
@@ -12,17 +24,17 @@ export function processResult(
   res: string
 ): ProcessResult {
   const disabledStatuses = [
-    'archived',
-    'blocked',
-    'cannot-fork',
-    'disabled',
-    'forbidden',
-    'fork',
-    'mirror',
-    'no-package-files',
-    'renamed',
-    'uninitiated',
-    'empty',
+    REPOSITORY_ARCHIVED,
+    REPOSITORY_BLOCKED,
+    REPOSITORY_CANNOT_FORK,
+    REPOSITORY_DISABLED,
+    REPOSITORY_ACCESS_FORBIDDEN,
+    REPOSITORY_FORKED,
+    REPOSITORY_MIRRORED,
+    MANAGER_NO_PACKAGE_FILES,
+    REPOSITORY_RENAMED,
+    REPOSITORY_UNINITIATED,
+    REPOSITORY_EMPTY,
   ];
   let status: ProcessStatus;
   // istanbul ignore next
diff --git a/test/datasource/docker.spec.ts b/test/datasource/docker.spec.ts
index 342232ac9972d737329240787bdb835ac7470088..804fbbe2ef64fd93da8903d8473942508ad88259 100644
--- a/test/datasource/docker.spec.ts
+++ b/test/datasource/docker.spec.ts
@@ -4,6 +4,7 @@ import _got from '../../lib/util/got';
 import * as docker from '../../lib/datasource/docker';
 import { getPkgReleases } from '../../lib/datasource';
 import * as _hostRules from '../../lib/util/host-rules';
+import { DATASOURCE_FAILURE } from '../../lib/constants/error-messages';
 
 const got: any = _got;
 const hostRules: any = _hostRules;
@@ -259,13 +260,13 @@ describe('api/docker', () => {
       got.mockRejectedValueOnce({ statusCode: 429 });
       await expect(
         docker.getDigest({ lookupName: 'some-dep' }, 'latest')
-      ).rejects.toThrow(Error('registry-failure'));
+      ).rejects.toThrow(Error(DATASOURCE_FAILURE));
     });
     it('should throw error for 5xx', async () => {
       got.mockRejectedValueOnce({ statusCode: 503 });
       await expect(
         docker.getDigest({ lookupName: 'some-dep' }, 'latest')
-      ).rejects.toThrow(Error('registry-failure'));
+      ).rejects.toThrow(Error(DATASOURCE_FAILURE));
     });
   });
   describe('getPkgReleases', () => {
diff --git a/test/datasource/github.spec.ts b/test/datasource/github.spec.ts
index b830f9bc291cee9c236ae752b226bf176a696a17..6255bb249e03652bbc909526faa4d8b6e29ffb38 100644
--- a/test/datasource/github.spec.ts
+++ b/test/datasource/github.spec.ts
@@ -4,6 +4,7 @@ import * as datasource from '../../lib/datasource';
 import * as github from '../../lib/datasource/github';
 import _got from '../../lib/util/got';
 import * as _hostRules from '../../lib/util/host-rules';
+import { PLATFORM_FAILURE } from '../../lib/constants/error-messages';
 
 jest.mock('../../lib/platform/github/gh-got-wrapper');
 jest.mock('../../lib/util/got');
@@ -65,10 +66,10 @@ describe('datasource/github', () => {
   describe('getPreset()', () => {
     it('passes up platform-failure', async () => {
       got.mockImplementationOnce(() => {
-        throw new Error('platform-failure');
+        throw new Error(PLATFORM_FAILURE);
       });
       await expect(github.getPreset('some/repo')).rejects.toThrow(
-        'platform-failure'
+        PLATFORM_FAILURE
       );
     });
     it('tries default then renovate', async () => {
diff --git a/test/datasource/hex.spec.ts b/test/datasource/hex.spec.ts
index 60fed3c182154a7675c3aadc0ca80673686f7a0a..5d79d88fd5b8ec399096000a08a6709d2a12cae4 100644
--- a/test/datasource/hex.spec.ts
+++ b/test/datasource/hex.spec.ts
@@ -2,6 +2,7 @@ import fs from 'fs';
 import _got from '../../lib/util/got';
 import * as _hostRules from '../../lib/util/host-rules';
 import { getPkgReleases } from '../../lib/datasource/hex';
+import { DATASOURCE_FAILURE } from '../../lib/constants/error-messages';
 
 const got: any = _got;
 const hostRules: any = _hostRules;
@@ -61,7 +62,7 @@ describe('datasource/hex', () => {
       );
       await expect(
         getPkgReleases({ lookupName: 'some_crate' })
-      ).rejects.toThrowError('registry-failure');
+      ).rejects.toThrowError(DATASOURCE_FAILURE);
     });
     it('throws for 5xx', async () => {
       got.mockImplementationOnce(() =>
@@ -71,7 +72,7 @@ describe('datasource/hex', () => {
       );
       await expect(
         getPkgReleases({ lookupName: 'some_crate' })
-      ).rejects.toThrowError('registry-failure');
+      ).rejects.toThrowError(DATASOURCE_FAILURE);
     });
     it('returns null for unknown error', async () => {
       got.mockImplementationOnce(() => {
diff --git a/test/datasource/maven.spec.ts b/test/datasource/maven.spec.ts
index 7581c3ab362d6180a41d470b491dd8fd8e71dc46..846143ae3425bc969ea969f7057e0a702bad1c7d 100644
--- a/test/datasource/maven.spec.ts
+++ b/test/datasource/maven.spec.ts
@@ -1,6 +1,7 @@
 import nock from 'nock';
 import fs from 'fs';
 import * as datasource from '../../lib/datasource';
+import { DATASOURCE_FAILURE } from '../../lib/constants/error-messages';
 
 const hostRules = require('../../lib/util/host-rules');
 
@@ -176,7 +177,7 @@ describe('datasource/maven', () => {
           lookupName: 'org:artifact',
           registryUrls: ['http://central.maven.org/maven2/'],
         })
-      ).rejects.toThrow(Error('registry-failure'));
+      ).rejects.toThrow(Error(DATASOURCE_FAILURE));
     });
 
     it('should return all versions of a specific library if a repository fails because invalid protocol', async () => {
diff --git a/test/datasource/npm/index.spec.ts b/test/datasource/npm/index.spec.ts
index 25cd89fadeffdf751660422d73acfdea9bc3bfd3..4d553b4cbb89bda3a600b5776b1616268316bab9 100644
--- a/test/datasource/npm/index.spec.ts
+++ b/test/datasource/npm/index.spec.ts
@@ -2,6 +2,7 @@ import _registryAuthToken from 'registry-auth-token';
 import nock from 'nock';
 import moment from 'moment';
 import * as npm from '../../../lib/datasource/npm';
+import { DATASOURCE_FAILURE } from '../../../lib/constants/error-messages';
 
 jest.mock('registry-auth-token');
 jest.mock('delay');
@@ -328,7 +329,7 @@ describe('api/npm', () => {
       .get('/foobar')
       .reply(503);
     await expect(npm.getPkgReleases({ lookupName: 'foobar' })).rejects.toThrow(
-      Error('registry-failure')
+      Error(DATASOURCE_FAILURE)
     );
   });
   it('should throw error for 408', async () => {
@@ -336,7 +337,7 @@ describe('api/npm', () => {
       .get('/foobar')
       .reply(408);
     await expect(npm.getPkgReleases({ lookupName: 'foobar' })).rejects.toThrow(
-      Error('registry-failure')
+      Error(DATASOURCE_FAILURE)
     );
   });
   it('should throw error for others', async () => {
diff --git a/test/platform/azure/index.spec.ts b/test/platform/azure/index.spec.ts
index 86c8c20ca885c6254f3632144e46ba8cb1bee051..cd5add0e2eea2ded54952c8fc968380d5f187c32 100644
--- a/test/platform/azure/index.spec.ts
+++ b/test/platform/azure/index.spec.ts
@@ -1,6 +1,7 @@
 import is from '@sindresorhus/is';
 import * as _hostRules from '../../../lib/util/host-rules';
 import { RepoParams } from '../../../lib/platform/common';
+import { REPOSITORY_DISABLED } from '../../../lib/constants/error-messages';
 
 describe('platform/azure', () => {
   let hostRules: jest.Mocked<typeof _hostRules>;
@@ -187,7 +188,7 @@ describe('platform/azure', () => {
       azureHelper.getFile.mockResolvedValueOnce('{ "enabled": false }');
       await expect(
         initRepo({ repository: 'some-repo', optimizeForDisabled: true })
-      ).rejects.toThrow('disabled');
+      ).rejects.toThrow(REPOSITORY_DISABLED);
     });
   });
 
diff --git a/test/platform/bitbucket-server/index.spec.ts b/test/platform/bitbucket-server/index.spec.ts
index 16c24a8f5c69e99b22ce8e45f30bc3a935e5bfd8..6b08d695f0d01a20027bc2be0b0853ce37516ca5 100644
--- a/test/platform/bitbucket-server/index.spec.ts
+++ b/test/platform/bitbucket-server/index.spec.ts
@@ -1,6 +1,11 @@
 import responses from './_fixtures/responses';
 import { GotApi, RepoParams } from '../../../lib/platform/common';
 import { Storage } from '../../../lib/platform/git/storage';
+import {
+  REPOSITORY_CHANGED,
+  REPOSITORY_DISABLED,
+  REPOSITORY_NOT_FOUND,
+} from '../../../lib/constants/error-messages';
 
 type BbsApi = typeof import('../../../lib/platform/bitbucket-server');
 
@@ -147,7 +152,7 @@ describe('platform/bitbucket-server', () => {
             body: { isLastPage: true, lines: ['{ "enabled": false }'] },
           } as any);
           await expect(initRepo({ optimizeForDisabled: true })).rejects.toThrow(
-            'disabled'
+            REPOSITORY_DISABLED
           );
         });
       });
@@ -268,10 +273,10 @@ describe('platform/bitbucket-server', () => {
 
           await expect(
             bitbucket.addReviewers(null as any, ['name'])
-          ).rejects.toThrow('not-found');
+          ).rejects.toThrow(REPOSITORY_NOT_FOUND);
 
           await expect(bitbucket.addReviewers(4, ['name'])).rejects.toThrow(
-            'not-found'
+            REPOSITORY_NOT_FOUND
           );
           api.put.mockReturnValueOnce(
             Promise.reject({
@@ -279,7 +284,7 @@ describe('platform/bitbucket-server', () => {
             })
           );
           await expect(bitbucket.addReviewers(5, ['name'])).rejects.toThrow(
-            'not-found'
+            REPOSITORY_NOT_FOUND
           );
 
           expect(api.get.mock.calls).toMatchSnapshot();
@@ -295,7 +300,7 @@ describe('platform/bitbucket-server', () => {
             })
           );
           await expect(bitbucket.addReviewers(5, ['name'])).rejects.toThrow(
-            'repository-changed'
+            REPOSITORY_CHANGED
           );
           expect(api.get.mock.calls).toMatchSnapshot();
           expect(api.put.mock.calls).toMatchSnapshot();
@@ -578,10 +583,10 @@ describe('platform/bitbucket-server', () => {
 
           await expect(
             bitbucket.updatePr(null as any, 'title', 'body')
-          ).rejects.toThrow('not-found');
+          ).rejects.toThrow(REPOSITORY_NOT_FOUND);
 
           await expect(bitbucket.updatePr(4, 'title', 'body')).rejects.toThrow(
-            'not-found'
+            REPOSITORY_NOT_FOUND
           );
           api.put.mockReturnValueOnce(
             Promise.reject({
@@ -589,7 +594,7 @@ describe('platform/bitbucket-server', () => {
             })
           );
           await expect(bitbucket.updatePr(5, 'title', 'body')).rejects.toThrow(
-            'not-found'
+            REPOSITORY_NOT_FOUND
           );
 
           expect(api.get.mock.calls).toMatchSnapshot();
@@ -605,7 +610,7 @@ describe('platform/bitbucket-server', () => {
             })
           );
           await expect(bitbucket.updatePr(5, 'title', 'body')).rejects.toThrow(
-            'repository-changed'
+            REPOSITORY_CHANGED
           );
           expect(api.get.mock.calls).toMatchSnapshot();
           expect(api.put.mock.calls).toMatchSnapshot();
@@ -642,9 +647,9 @@ describe('platform/bitbucket-server', () => {
 
           await expect(
             bitbucket.mergePr(null as any, 'branch')
-          ).rejects.toThrow('not-found');
+          ).rejects.toThrow(REPOSITORY_NOT_FOUND);
           await expect(bitbucket.mergePr(4, 'branch')).rejects.toThrow(
-            'not-found'
+            REPOSITORY_NOT_FOUND
           );
 
           api.post.mockReturnValueOnce(
@@ -654,7 +659,7 @@ describe('platform/bitbucket-server', () => {
           );
 
           await expect(bitbucket.mergePr(5, 'branch')).rejects.toThrow(
-            'not-found'
+            REPOSITORY_NOT_FOUND
           );
           expect(api.get.mock.calls).toMatchSnapshot();
           expect(api.post.mock.calls).toMatchSnapshot();
@@ -817,7 +822,7 @@ Followed by some information.
           await initRepo();
           await expect(
             bitbucket.getBranchStatus('somebranch', true)
-          ).rejects.toThrow('repository-changed');
+          ).rejects.toThrow(REPOSITORY_CHANGED);
         });
       });
 
diff --git a/test/platform/bitbucket/index.spec.ts b/test/platform/bitbucket/index.spec.ts
index 9e73e4d28486103f638a892d9c143f2167d65047..39f97af35be112f4614ba49224817d0b509cb7d7 100644
--- a/test/platform/bitbucket/index.spec.ts
+++ b/test/platform/bitbucket/index.spec.ts
@@ -1,6 +1,7 @@
 import URL from 'url';
 import responses from './_fixtures/responses';
 import { GotApi, RepoParams } from '../../../lib/platform/common';
+import { REPOSITORY_DISABLED } from '../../../lib/constants/error-messages';
 
 describe('platform/bitbucket', () => {
   let bitbucket: typeof import('../../../lib/platform/bitbucket');
@@ -127,7 +128,7 @@ describe('platform/bitbucket', () => {
       expect.assertions(1);
       await expect(
         initRepo({ repository: 'some/empty', optimizeForDisabled: true })
-      ).rejects.toThrow('disabled');
+      ).rejects.toThrow(REPOSITORY_DISABLED);
     });
   });
 
diff --git a/test/platform/github/gh-got-wrapper.spec.ts b/test/platform/github/gh-got-wrapper.spec.ts
index c618d75223464101448892f77c4acc14ee8efc23..97b383aad52f89f35f0d8f451c5288290d322acc 100644
--- a/test/platform/github/gh-got-wrapper.spec.ts
+++ b/test/platform/github/gh-got-wrapper.spec.ts
@@ -2,6 +2,10 @@ import delay from 'delay';
 import { Response } from 'got';
 import _got from '../../../lib/util/got';
 import { api } from '../../../lib/platform/github/gh-got-wrapper';
+import {
+  PLATFORM_BAD_CREDENTIALS,
+  PLATFORM_RATE_LIMIT_EXCEEDED,
+} from '../../../lib/constants/error-messages';
 
 jest.mock('../../../lib/util/got');
 jest.mock('delay');
@@ -104,7 +108,7 @@ describe('platform/gh-got-wrapper', () => {
     );
     const e = await getError();
     expect(e).toBeDefined();
-    expect(e.message).toEqual('bad-credentials');
+    expect(e.message).toEqual(PLATFORM_BAD_CREDENTIALS);
   });
   it('should throw platform failure', async () => {
     got.mockImplementationOnce(() =>
@@ -185,7 +189,7 @@ describe('platform/gh-got-wrapper', () => {
     got.mockRejectedValueOnce(gotErr);
     const e = await getError();
     expect(e).toBeDefined();
-    expect(e.message).toEqual('platform-failure');
+    expect(e.message).toEqual(PLATFORM_RATE_LIMIT_EXCEEDED);
   });
   it('should throw on repository change', async () => {
     const gotErr = {
diff --git a/test/platform/github/index.spec.ts b/test/platform/github/index.spec.ts
index aa10e5c0ef9623c82b70395d2c37195da732826a..a56630f95476293ca654717a4b3eb632485ccf5d 100644
--- a/test/platform/github/index.spec.ts
+++ b/test/platform/github/index.spec.ts
@@ -1,5 +1,10 @@
 import fs from 'fs-extra';
 import { GotApi, GotResponse } from '../../../lib/platform/common';
+import {
+  REPOSITORY_DISABLED,
+  REPOSITORY_NOT_FOUND,
+  REPOSITORY_RENAMED,
+} from '../../../lib/constants/error-messages';
 
 describe('platform/github', () => {
   let github: typeof import('../../../lib/platform/github');
@@ -220,7 +225,7 @@ describe('platform/github', () => {
           repository: 'some/repo',
           optimizeForDisabled: true,
         } as any)
-      ).rejects.toThrow('disabled');
+      ).rejects.toThrow(REPOSITORY_DISABLED);
     });
     it('should rebase', async () => {
       function squashInitRepo(args: any) {
@@ -443,7 +448,7 @@ describe('platform/github', () => {
         github.initRepo({
           repository: 'some/repo',
         } as any)
-      ).rejects.toThrow('not-found');
+      ).rejects.toThrow(REPOSITORY_NOT_FOUND);
     });
     it('should throw error if renamed', async () => {
       api.get.mockReturnValueOnce({
@@ -458,7 +463,7 @@ describe('platform/github', () => {
           includeForks: true,
           repository: 'some/repo',
         } as any)
-      ).rejects.toThrow('renamed');
+      ).rejects.toThrow(REPOSITORY_RENAMED);
     });
   });
   describe('getRepoForceRebase', () => {
diff --git a/test/platform/gitlab/index.spec.ts b/test/platform/gitlab/index.spec.ts
index 3ada3d3124104f5219d4884049b67911023fea85..254171e3db0c4dea221e360e73d65d035bdfff7e 100644
--- a/test/platform/gitlab/index.spec.ts
+++ b/test/platform/gitlab/index.spec.ts
@@ -1,4 +1,11 @@
 import * as _hostRules from '../../../lib/util/host-rules';
+import {
+  REPOSITORY_ARCHIVED,
+  REPOSITORY_CHANGED,
+  REPOSITORY_DISABLED,
+  REPOSITORY_EMPTY,
+  REPOSITORY_MIRRORED,
+} from '../../../lib/constants/error-messages';
 
 describe('platform/gitlab', () => {
   let gitlab: typeof import('../../../lib/platform/gitlab');
@@ -194,7 +201,7 @@ describe('platform/gitlab', () => {
           localDir: '',
           optimizeForDisabled: true,
         })
-      ).rejects.toThrow(Error('disabled'));
+      ).rejects.toThrow(Error(REPOSITORY_DISABLED));
     });
     it(`should escape all forward slashes in project names`, async () => {
       api.get.mockReturnValue({ body: [] } as any);
@@ -221,7 +228,7 @@ describe('platform/gitlab', () => {
           localDir: '',
           optimizeForDisabled: false,
         })
-      ).rejects.toThrow(Error('archived'));
+      ).rejects.toThrow(Error(REPOSITORY_ARCHIVED));
     });
     it('should throw an error if repository is a mirror', async () => {
       api.get.mockReturnValue({ body: { mirror: true } } as any);
@@ -231,7 +238,7 @@ describe('platform/gitlab', () => {
           localDir: '',
           optimizeForDisabled: false,
         })
-      ).rejects.toThrow(Error('mirror'));
+      ).rejects.toThrow(Error(REPOSITORY_MIRRORED));
     });
     it('should throw an error if repository access is disabled', async () => {
       api.get.mockReturnValue({
@@ -243,7 +250,7 @@ describe('platform/gitlab', () => {
           localDir: '',
           optimizeForDisabled: false,
         })
-      ).rejects.toThrow(Error('disabled'));
+      ).rejects.toThrow(Error(REPOSITORY_DISABLED));
     });
     it('should throw an error if MRs are disabled', async () => {
       api.get.mockReturnValue({
@@ -255,7 +262,7 @@ describe('platform/gitlab', () => {
           localDir: '',
           optimizeForDisabled: false,
         })
-      ).rejects.toThrow(Error('disabled'));
+      ).rejects.toThrow(Error(REPOSITORY_DISABLED));
     });
     it('should throw an error if repository has empty_repo property', async () => {
       api.get.mockReturnValue({ body: { empty_repo: true } } as any);
@@ -265,7 +272,7 @@ describe('platform/gitlab', () => {
           localDir: '',
           optimizeForDisabled: false,
         })
-      ).rejects.toThrow(Error('empty'));
+      ).rejects.toThrow(Error(REPOSITORY_EMPTY));
     });
     it('should throw an error if repository is empty', async () => {
       api.get.mockReturnValue({ body: { default_branch: null } } as any);
@@ -275,7 +282,7 @@ describe('platform/gitlab', () => {
           localDir: '',
           optimizeForDisabled: false,
         })
-      ).rejects.toThrow(Error('empty'));
+      ).rejects.toThrow(Error(REPOSITORY_EMPTY));
     });
     it('should fall back if http_url_to_repo is empty', async () => {
       api.get.mockReturnValue({
@@ -454,7 +461,7 @@ describe('platform/gitlab', () => {
       }));
       await initRepo();
       await expect(gitlab.getBranchStatus('somebranch', [])).rejects.toThrow(
-        'repository-changed'
+        REPOSITORY_CHANGED
       );
     });
   });
diff --git a/test/platform/index.spec.ts b/test/platform/index.spec.ts
index 33d7b8d5fc48cab3b69c3afb784c0fc0f856309f..22fd26ac57f5b7fee85e18c49c1602f2b63143c1 100644
--- a/test/platform/index.spec.ts
+++ b/test/platform/index.spec.ts
@@ -3,6 +3,7 @@ import * as gitlab from '../../lib/platform/gitlab';
 import * as azure from '../../lib/platform/azure';
 import * as bitbucket from '../../lib/platform/bitbucket';
 import * as bitbucketServer from '../../lib/platform/bitbucket-server';
+import { PLATFORM_NOT_FOUND } from '../../lib/constants/error-messages';
 
 import * as platform from '../../lib/platform';
 
@@ -14,7 +15,7 @@ describe('platform', () => {
   });
   it('throws if no platform', () => {
     expect(() => platform.platform.initPlatform({})).toThrow(
-      'platform-not-found'
+      PLATFORM_NOT_FOUND
     );
   });
   it('throws if wrong platform', async () => {
diff --git a/test/util/regex.spec.ts b/test/util/regex.spec.ts
index 64ea780e9c905464f88bd2e63256aac51da4e1cf..3ad5a9ea356d631fb119ea92c9ff9f6b525e6962 100644
--- a/test/util/regex.spec.ts
+++ b/test/util/regex.spec.ts
@@ -1,5 +1,6 @@
 import RE2 from 're2';
 import { regEx } from '../../lib/util/regex';
+import { CONFIG_VALIDATION } from '../../lib/constants/error-messages';
 
 describe('util/regex', () => {
   beforeEach(() => {
@@ -10,7 +11,7 @@ describe('util/regex', () => {
     expect(regEx('foo')).toBeInstanceOf(RE2);
   });
   it('throws unsafe 2', () => {
-    expect(() => regEx(`x++`)).toThrow('config-validation');
+    expect(() => regEx(`x++`)).toThrow(CONFIG_VALIDATION);
   });
 
   it('Falls back to RegExp', () => {
diff --git a/test/versioning/regex.spec.ts b/test/versioning/regex.spec.ts
index 5cc01583ea229d2c772547035803377fb49af2c9..c1bf66f8b6939439e45bb2f2f87470a2866e8794 100644
--- a/test/versioning/regex.spec.ts
+++ b/test/versioning/regex.spec.ts
@@ -1,4 +1,5 @@
 import { get, VersioningApi } from '../../lib/versioning';
+import { CONFIG_VALIDATION } from '../../lib/constants/error-messages';
 
 describe('regex', () => {
   const regex: VersioningApi = get(
@@ -16,7 +17,7 @@ describe('regex', () => {
       '^(?<major>\\d+)?(?<=y)x$',
     ]) {
       it(re, () => {
-        expect(() => get(`regex:${re}`)).toThrow('config-validation');
+        expect(() => get(`regex:${re}`)).toThrow(CONFIG_VALIDATION);
       });
     }
   });
diff --git a/test/workers/branch/index.spec.ts b/test/workers/branch/index.spec.ts
index 0995ca95317fb72464378ce2ddc8cadfb0957e04..7b758d0171e0f9b79c8890fcd32c9226bde19fda 100644
--- a/test/workers/branch/index.spec.ts
+++ b/test/workers/branch/index.spec.ts
@@ -10,6 +10,10 @@ import * as _prWorker from '../../../lib/workers/pr';
 import * as _getUpdated from '../../../lib/workers/branch/get-updated';
 import { defaultConfig, platform, mocked } from '../../util';
 import { BranchConfig } from '../../../lib/workers/common';
+import {
+  MANAGER_LOCKFILE_ERROR,
+  REPOSITORY_CHANGED,
+} from '../../../lib/constants/error-messages';
 
 jest.mock('../../../lib/workers/branch/get-updated');
 jest.mock('../../../lib/workers/branch/schedule');
@@ -151,7 +155,7 @@ describe('workers/branch', () => {
         isModified: true,
       } as never);
       await expect(branchWorker.processBranch(config)).rejects.toThrow(
-        /repository-changed/
+        REPOSITORY_CHANGED
       );
     });
     it('does not skip branch if edited PR found with rebaseLabel', async () => {
@@ -357,7 +361,7 @@ describe('workers/branch', () => {
       prWorker.checkAutoMerge.mockResolvedValueOnce(true);
       config.releaseTimestamp = new Date().toISOString();
       await expect(branchWorker.processBranch(config)).rejects.toThrow(
-        Error('lockfile-error')
+        Error(MANAGER_LOCKFILE_ERROR)
       );
     });
     it('ensures PR and adds lock file error comment recreate closed', async () => {
diff --git a/test/workers/repository/error-config.spec.ts b/test/workers/repository/error-config.spec.ts
index fab8668426de047818a28775d7a0b5e832fb7ff0..b9b6d831dde449d9c7a2e4749469a99fa7fe2451 100644
--- a/test/workers/repository/error-config.spec.ts
+++ b/test/workers/repository/error-config.spec.ts
@@ -1,5 +1,5 @@
 import { mock } from 'jest-mock-extended';
-
+import { CONFIG_VALIDATION } from '../../../lib/constants/error-messages';
 import { raiseConfigWarningIssue } from '../../../lib/workers/repository/error-config';
 import { RenovateConfig, getConfig, platform } from '../../util';
 import { Pr } from '../../../lib/platform';
@@ -15,7 +15,7 @@ beforeEach(() => {
 describe('workers/repository/error-config', () => {
   describe('raiseConfigWarningIssue()', () => {
     it('creates issues', async () => {
-      const error = new Error('config-validation');
+      const error = new Error(CONFIG_VALIDATION);
       error.configFile = 'package.json';
       error.validationMessage = 'some-message';
       platform.ensureIssue.mockResolvedValueOnce('created');
@@ -23,7 +23,7 @@ describe('workers/repository/error-config', () => {
       expect(res).toBeUndefined();
     });
     it('creates issues (dryRun)', async () => {
-      const error = new Error('config-validation');
+      const error = new Error(CONFIG_VALIDATION);
       error.configFile = 'package.json';
       error.validationMessage = 'some-message';
       platform.ensureIssue.mockResolvedValueOnce('created');
@@ -34,7 +34,7 @@ describe('workers/repository/error-config', () => {
       expect(res).toBeUndefined();
     });
     it('handles onboarding', async () => {
-      const error = new Error('config-validation');
+      const error = new Error(CONFIG_VALIDATION);
       error.configFile = 'package.json';
       error.validationMessage = 'some-message';
       platform.getBranchPr.mockResolvedValue({
@@ -46,7 +46,7 @@ describe('workers/repository/error-config', () => {
       expect(res).toBeUndefined();
     });
     it('handles onboarding (dryRun)', async () => {
-      const error = new Error('config-validation');
+      const error = new Error(CONFIG_VALIDATION);
       error.configFile = 'package.json';
       error.validationMessage = 'some-message';
       platform.getBranchPr.mockResolvedValue({
diff --git a/test/workers/repository/error.spec.ts b/test/workers/repository/error.spec.ts
index 0c72cb47318a90771124997266e21e313e7569c9..5ab5cae31fbeb4096db7be45b2204c0c2a460b55 100644
--- a/test/workers/repository/error.spec.ts
+++ b/test/workers/repository/error.spec.ts
@@ -1,4 +1,31 @@
 import handleError from '../../../lib/workers/repository/error';
+import {
+  CONFIG_VALIDATION,
+  DATASOURCE_FAILURE,
+  MANAGER_LOCKFILE_ERROR,
+  MANAGER_NO_PACKAGE_FILES,
+  PLATFORM_AUTHENTICATION_ERROR,
+  PLATFORM_BAD_CREDENTIALS,
+  PLATFORM_FAILURE,
+  PLATFORM_INTEGRATION_UNAUTHORIZED,
+  PLATFORM_RATE_LIMIT_EXCEEDED,
+  REPOSITORY_ACCESS_FORBIDDEN,
+  REPOSITORY_ARCHIVED,
+  REPOSITORY_BLOCKED,
+  REPOSITORY_CANNOT_FORK,
+  REPOSITORY_CHANGED,
+  REPOSITORY_DISABLED,
+  REPOSITORY_EMPTY,
+  REPOSITORY_FORKED,
+  REPOSITORY_MIRRORED,
+  REPOSITORY_NO_VULNERABILITY,
+  REPOSITORY_NOT_FOUND,
+  REPOSITORY_RENAMED,
+  REPOSITORY_TEMPORARY_ERROR,
+  REPOSITORY_UNINITIATED,
+  SYSTEM_INSUFFICIENT_DISK_SPACE,
+  UNKNOWN_ERROR,
+} from '../../../lib/constants/error-messages';
 import { RenovateConfig, getConfig } from '../../util';
 
 jest.mock('../../../lib/workers/repository/error-config');
@@ -12,30 +39,30 @@ beforeEach(() => {
 describe('workers/repository/error', () => {
   describe('handleError()', () => {
     const errors = [
-      'uninitiated',
-      'empty',
-      'disabled',
-      'repository-changed',
-      'fork',
-      'no-package-files',
-      'config-validation',
-      'registry-failure',
-      'archived',
-      'mirror',
-      'renamed',
-      'blocked',
-      'not-found',
-      'forbidden',
-      'bad-credentials',
-      'rate-limit-exceeded',
-      'lockfile-error',
-      'disk-space',
-      'platform-failure',
-      'no-vulnerability-alerts',
-      'cannot-fork',
-      'integration-unauthorized',
-      'authentication-error',
-      'temporary-error',
+      REPOSITORY_UNINITIATED,
+      REPOSITORY_EMPTY,
+      REPOSITORY_DISABLED,
+      REPOSITORY_CHANGED,
+      REPOSITORY_FORKED,
+      MANAGER_NO_PACKAGE_FILES,
+      CONFIG_VALIDATION,
+      DATASOURCE_FAILURE,
+      REPOSITORY_ARCHIVED,
+      REPOSITORY_MIRRORED,
+      REPOSITORY_RENAMED,
+      REPOSITORY_BLOCKED,
+      REPOSITORY_NOT_FOUND,
+      REPOSITORY_ACCESS_FORBIDDEN,
+      PLATFORM_BAD_CREDENTIALS,
+      PLATFORM_RATE_LIMIT_EXCEEDED,
+      MANAGER_LOCKFILE_ERROR,
+      SYSTEM_INSUFFICIENT_DISK_SPACE,
+      PLATFORM_FAILURE,
+      REPOSITORY_NO_VULNERABILITY,
+      REPOSITORY_CANNOT_FORK,
+      PLATFORM_INTEGRATION_UNAUTHORIZED,
+      PLATFORM_AUTHENTICATION_ERROR,
+      REPOSITORY_TEMPORARY_ERROR,
     ];
     errors.forEach(err => {
       it(`errors ${err}`, async () => {
@@ -48,18 +75,18 @@ describe('workers/repository/error', () => {
         "fatal: unable to access 'https://**redacted**@gitlab.com/learnox/learnox.git/': The requested URL returned error: 500\n"
       );
       const res = await handleError(config, gitError);
-      expect(res).toEqual('platform-failure');
+      expect(res).toEqual(PLATFORM_FAILURE);
     });
     it('rewrites git remote error', async () => {
       const gitError = new Error(
         'fatal: remote error: access denied or repository not exported: /b/nw/bd/27/47/159945428/108610112.git\n'
       );
       const res = await handleError(config, gitError);
-      expect(res).toEqual('platform-failure');
+      expect(res).toEqual(PLATFORM_FAILURE);
     });
     it('handles unknown error', async () => {
       const res = await handleError(config, new Error('abcdefg'));
-      expect(res).toEqual('unknown-error');
+      expect(res).toEqual(UNKNOWN_ERROR);
     });
   });
 });
diff --git a/test/workers/repository/init/vulnerability.spec.ts b/test/workers/repository/init/vulnerability.spec.ts
index 715af5e5e032050306536744988219fb439a3342..adcf089f4b302a0b72dcd36a6a7b398ae86632f2 100644
--- a/test/workers/repository/init/vulnerability.spec.ts
+++ b/test/workers/repository/init/vulnerability.spec.ts
@@ -1,5 +1,6 @@
 import { detectVulnerabilityAlerts } from '../../../../lib/workers/repository/init/vulnerability';
 import { platform, defaultConfig, RenovateConfig } from '../../../util';
+import { REPOSITORY_NO_VULNERABILITY } from '../../../../lib/constants/error-messages';
 
 let config: RenovateConfig;
 beforeEach(() => {
@@ -26,7 +27,7 @@ describe('workers/repository/init/vulnerability', () => {
       config.vulnerabilityAlertsOnly = true;
       platform.getVulnerabilityAlerts.mockResolvedValue([]);
       await expect(detectVulnerabilityAlerts(config)).rejects.toThrow(
-        /no-vulnerability-alerts/
+        REPOSITORY_NO_VULNERABILITY
       );
     });
     it('returns alerts', async () => {
diff --git a/test/workers/repository/process/lookup/index.spec.ts b/test/workers/repository/process/lookup/index.spec.ts
index 8b02b70b89dcc49b42e7059f2533c7b30bc9699a..fa9b276892ed7d447b6bf161ea4ebb1e6256220a 100644
--- a/test/workers/repository/process/lookup/index.spec.ts
+++ b/test/workers/repository/process/lookup/index.spec.ts
@@ -10,6 +10,7 @@ import typescriptJson from '../../../../config/npm/_fixtures/typescript.json';
 import * as _docker from '../../../../../lib/datasource/docker';
 import * as _gitSubmodules from '../../../../../lib/datasource/git-submodules';
 import { mocked, getConfig } from '../../../../util';
+import { CONFIG_VALIDATION } from '../../../../../lib/constants/error-messages';
 
 jest.mock('../../../../../lib/datasource/docker');
 jest.mock('../../../../../lib/datasource/git-submodules');
@@ -179,7 +180,7 @@ describe('workers/repository/process/lookup', () => {
         .get('/q')
         .reply(200, qJson);
       await expect(lookup.lookupUpdates(config)).rejects.toThrow(
-        Error('config-validation')
+        Error(CONFIG_VALIDATION)
       );
     });
     it('returns minor update if separate patches not configured', async () => {