diff --git a/lib/workers/branch/index.spec.ts b/lib/workers/branch/index.spec.ts
index 2286cb6a5823ac015f6bee624a0be62640fb45d6..17b33e734fa9e21f3ec6a737a7988e5918f56001 100644
--- a/lib/workers/branch/index.spec.ts
+++ b/lib/workers/branch/index.spec.ts
@@ -21,7 +21,7 @@ import * as _mergeConfidence from '../../util/merge-confidence';
 import * as _sanitize from '../../util/sanitize';
 import * as _limits from '../global/limits';
 import * as _prWorker from '../pr';
-import type { EnsurePrResult } from '../pr';
+import type { ResultWithPr } from '../pr';
 import * as _prAutomerge from '../pr/automerge';
 import type { Pr } from '../repository/onboarding/branch/check';
 import type { BranchConfig, BranchUpgradeConfig } from '../types';
@@ -99,6 +99,7 @@ describe('workers/branch/index', () => {
 
       platform.massageMarkdown.mockImplementation((prBody) => prBody);
       prWorker.ensurePr.mockResolvedValue({
+        type: 'with-pr',
         pr: partial<Pr>({
           title: '',
           sourceBranch: '',
@@ -381,6 +382,7 @@ describe('workers/branch/index', () => {
       });
       git.branchExists.mockReturnValue(true);
       prWorker.ensurePr.mockResolvedValueOnce({
+        type: 'without-pr',
         prBlockedBy: 'RateLimited',
       });
       limits.isLimitReached.mockReturnValue(false);
@@ -503,6 +505,7 @@ describe('workers/branch/index', () => {
       commit.commitFilesToBranch.mockResolvedValueOnce(null);
       automerge.tryBranchAutomerge.mockResolvedValueOnce('failed');
       prWorker.ensurePr.mockResolvedValueOnce({
+        type: 'without-pr',
         prBlockedBy: 'NeedsApproval',
       });
       expect(await branchWorker.processBranch(config)).toEqual({
@@ -524,6 +527,7 @@ describe('workers/branch/index', () => {
       commit.commitFilesToBranch.mockResolvedValueOnce(null);
       automerge.tryBranchAutomerge.mockResolvedValueOnce('failed');
       prWorker.ensurePr.mockResolvedValueOnce({
+        type: 'without-pr',
         prBlockedBy: 'AwaitingTests',
       });
       expect(await branchWorker.processBranch(config)).toEqual({
@@ -545,6 +549,7 @@ describe('workers/branch/index', () => {
       commit.commitFilesToBranch.mockResolvedValueOnce(null);
       automerge.tryBranchAutomerge.mockResolvedValueOnce('no automerge');
       prWorker.ensurePr.mockResolvedValueOnce({
+        type: 'without-pr',
         prBlockedBy: 'BranchAutomerge',
       });
       expect(await branchWorker.processBranch(config)).toEqual({
@@ -566,6 +571,7 @@ describe('workers/branch/index', () => {
       commit.commitFilesToBranch.mockResolvedValueOnce(null);
       automerge.tryBranchAutomerge.mockResolvedValueOnce('failed');
       prWorker.ensurePr.mockResolvedValueOnce({
+        type: 'without-pr',
         prBlockedBy: 'Error',
       });
       expect(await branchWorker.processBranch(config)).toEqual({
@@ -587,6 +593,7 @@ describe('workers/branch/index', () => {
       commit.commitFilesToBranch.mockResolvedValueOnce(null);
       automerge.tryBranchAutomerge.mockResolvedValueOnce('failed');
       prWorker.ensurePr.mockResolvedValueOnce({
+        type: 'without-pr',
         prBlockedBy: 'whoops' as any,
       });
       expect(await branchWorker.processBranch(config)).toEqual({
@@ -630,8 +637,9 @@ describe('workers/branch/index', () => {
       git.branchExists.mockReturnValue(true);
       automerge.tryBranchAutomerge.mockResolvedValueOnce('failed');
       prWorker.ensurePr.mockResolvedValueOnce({
+        type: 'with-pr',
         pr: {},
-      } as EnsurePrResult);
+      } as ResultWithPr);
       prAutomerge.checkAutoMerge.mockResolvedValueOnce({ automerged: true });
       commit.commitFilesToBranch.mockResolvedValueOnce(null);
       await branchWorker.processBranch({ ...config, automerge: true });
@@ -650,8 +658,9 @@ describe('workers/branch/index', () => {
       git.branchExists.mockReturnValue(true);
       automerge.tryBranchAutomerge.mockResolvedValueOnce('stale');
       prWorker.ensurePr.mockResolvedValueOnce({
+        type: 'with-pr',
         pr: {},
-      } as EnsurePrResult);
+      } as ResultWithPr);
       prAutomerge.checkAutoMerge.mockResolvedValueOnce({ automerged: false });
       commit.commitFilesToBranch.mockResolvedValueOnce(null);
       await branchWorker.processBranch({
@@ -674,8 +683,9 @@ describe('workers/branch/index', () => {
       git.branchExists.mockReturnValue(true);
       automerge.tryBranchAutomerge.mockResolvedValueOnce('failed');
       prWorker.ensurePr.mockResolvedValueOnce({
+        type: 'with-pr',
         pr: {},
-      } as EnsurePrResult);
+      } as ResultWithPr);
       prAutomerge.checkAutoMerge.mockResolvedValueOnce({ automerged: true });
       commit.commitFilesToBranch.mockResolvedValueOnce(null);
       await branchWorker.processBranch(config);
@@ -694,8 +704,9 @@ describe('workers/branch/index', () => {
       git.branchExists.mockReturnValue(true);
       automerge.tryBranchAutomerge.mockResolvedValueOnce('failed');
       prWorker.ensurePr.mockResolvedValueOnce({
+        type: 'with-pr',
         pr: {},
-      } as EnsurePrResult);
+      } as ResultWithPr);
       prAutomerge.checkAutoMerge.mockResolvedValueOnce({ automerged: true });
       config.releaseTimestamp = '2018-04-26T05:15:51.877Z';
       commit.commitFilesToBranch.mockResolvedValueOnce(null);
@@ -715,8 +726,9 @@ describe('workers/branch/index', () => {
       git.branchExists.mockReturnValue(true);
       automerge.tryBranchAutomerge.mockResolvedValueOnce('failed');
       prWorker.ensurePr.mockResolvedValueOnce({
+        type: 'with-pr',
         pr: {},
-      } as EnsurePrResult);
+      } as ResultWithPr);
       prAutomerge.checkAutoMerge.mockResolvedValueOnce({ automerged: true });
       config.releaseTimestamp = new Date().toISOString();
       commit.commitFilesToBranch.mockResolvedValueOnce(null);
@@ -736,8 +748,9 @@ describe('workers/branch/index', () => {
       git.branchExists.mockReturnValue(false);
       automerge.tryBranchAutomerge.mockResolvedValueOnce('failed');
       prWorker.ensurePr.mockResolvedValueOnce({
+        type: 'with-pr',
         pr: {},
-      } as EnsurePrResult);
+      } as ResultWithPr);
       prAutomerge.checkAutoMerge.mockResolvedValueOnce({ automerged: true });
       config.releaseTimestamp = new Date().toISOString();
       await expect(branchWorker.processBranch(config)).rejects.toThrow(
@@ -756,8 +769,9 @@ describe('workers/branch/index', () => {
       git.branchExists.mockReturnValue(true);
       automerge.tryBranchAutomerge.mockResolvedValueOnce('failed');
       prWorker.ensurePr.mockResolvedValueOnce({
+        type: 'with-pr',
         pr: {},
-      } as EnsurePrResult);
+      } as ResultWithPr);
       prAutomerge.checkAutoMerge.mockResolvedValueOnce({ automerged: true });
       commit.commitFilesToBranch.mockResolvedValueOnce(null);
       await branchWorker.processBranch(config);
@@ -890,8 +904,9 @@ describe('workers/branch/index', () => {
       git.isBranchModified.mockResolvedValueOnce(true);
       schedule.isScheduledNow.mockReturnValueOnce(false);
       prWorker.ensurePr.mockResolvedValueOnce({
+        type: 'with-pr',
         pr: {},
-      } as EnsurePrResult);
+      } as ResultWithPr);
       commit.commitFilesToBranch.mockResolvedValueOnce(null);
       GlobalConfig.set({ ...adminConfig, dryRun: true });
       expect(
diff --git a/lib/workers/branch/index.ts b/lib/workers/branch/index.ts
index 5c3377dff20cb78d64688dd8c46c0f75aed500d9..bebe650458e2ba19a1e07510ebfd05c21ea877f5 100644
--- a/lib/workers/branch/index.ts
+++ b/lib/workers/branch/index.ts
@@ -619,9 +619,10 @@ export async function processBranch(
     logger.debug(
       `There are ${config.errors.length} errors and ${config.warnings.length} warnings`
     );
-    const { prBlockedBy, pr } = await ensurePr(config);
-    branchPr = pr;
-    if (prBlockedBy) {
+    const ensurePrResult = await ensurePr(config);
+    if (ensurePrResult.type === 'without-pr') {
+      const { prBlockedBy } = ensurePrResult;
+      branchPr = null;
       if (prBlockedBy === 'RateLimited' && !config.isVulnerabilityAlert) {
         logger.debug('Reached PR limit - skipping PR creation');
         return {
@@ -654,7 +655,9 @@ export async function processBranch(
       logger.warn({ prBlockedBy }, 'Unknown PrBlockedBy result');
       return { branchExists, prBlockedBy, result: BranchResult.Error };
     }
-    if (pr) {
+    if (ensurePrResult.type === 'with-pr') {
+      const { pr } = ensurePrResult;
+      branchPr = pr;
       if (config.artifactErrors?.length) {
         logger.warn(
           { artifactErrors: config.artifactErrors },
diff --git a/lib/workers/pr/index.spec.ts b/lib/workers/pr/index.spec.ts
index 25bbf2595d2919cb68546ade97833e076b30660e..d48c662774ecb7aa59fcb43e45b74e0bb5fc2e46 100644
--- a/lib/workers/pr/index.spec.ts
+++ b/lib/workers/pr/index.spec.ts
@@ -9,6 +9,7 @@ import * as _changelogHelper from './changelog';
 import type { ChangeLogResult } from './changelog';
 import * as codeOwners from './code-owners';
 import * as prWorker from '.';
+import type { EnsurePrResult, ResultWithPr, ResultWithoutPr } from '.';
 
 const codeOwnersMock = mocked(codeOwners);
 const changelogHelper = mocked(_changelogHelper);
@@ -94,6 +95,20 @@ function setupGitlabChangelogMock() {
   gitlabChangelogHelper.getChangeLogJSON.mockResolvedValue(resultValue);
 }
 
+function isResultWithPr(value: EnsurePrResult): asserts value is ResultWithPr {
+  if (value.type !== 'with-pr') {
+    throw new TypeError();
+  }
+}
+
+function isResultWithoutPr(
+  value: EnsurePrResult
+): asserts value is ResultWithoutPr {
+  if (value.type !== 'without-pr') {
+    throw new TypeError();
+  }
+}
+
 describe('workers/pr/index', () => {
   describe('checkAutoMerge(pr, config)', () => {
     let config: BranchConfig;
@@ -205,22 +220,23 @@ describe('workers/pr/index', () => {
       });
       config.newValue = '1.2.0';
       platform.getBranchPr.mockResolvedValueOnce(existingPr);
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toBeDefined();
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toBeDefined();
     });
     it('should return null if waiting for success', async () => {
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.red);
       config.prCreation = 'status-success';
-      const { prBlockedBy, pr } = await prWorker.ensurePr(config);
-      expect(prBlockedBy).toBe('AwaitingTests');
-      expect(pr).toBeUndefined();
+      const result = await prWorker.ensurePr(config);
+      isResultWithoutPr(result);
+      expect(result.prBlockedBy).toBe('AwaitingTests');
     });
     it('should return needs-approval if prCreation set to approval', async () => {
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
       config.prCreation = 'approval';
-      const { prBlockedBy, pr } = await prWorker.ensurePr(config);
-      expect(prBlockedBy).toBe('NeedsApproval');
-      expect(pr).toBeUndefined();
+      const result = await prWorker.ensurePr(config);
+      isResultWithoutPr(result);
+      expect(result.prBlockedBy).toBe('NeedsApproval');
     });
     it('should create PR if success for gitlab deps', async () => {
       setupGitlabChangelogMock();
@@ -233,8 +249,9 @@ describe('workers/pr/index', () => {
       config.prCreation = 'status-success';
       config.automerge = true;
       config.schedule = ['before 5am'];
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
       expect(platform.createPr.mock.calls[0]).toMatchSnapshot([
         {
           prTitle: 'Update dependency dummy to v1.1.0',
@@ -253,8 +270,9 @@ describe('workers/pr/index', () => {
       config.prCreation = 'status-success';
       config.automerge = true;
       config.schedule = ['before 5am'];
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
       expect(platform.createPr.mock.calls[0]).toMatchSnapshot([
         {
           prTitle: 'Update dependency dummy to v1.1.0',
@@ -270,8 +288,9 @@ describe('workers/pr/index', () => {
       config.automerge = true;
       config.schedule = ['before 5am'];
       limits.isLimitReached.mockReturnValueOnce(true);
-      const { prBlockedBy } = await prWorker.ensurePr(config);
-      expect(prBlockedBy).toBe('RateLimited');
+      const result = await prWorker.ensurePr(config);
+      isResultWithoutPr(result);
+      expect(result.prBlockedBy).toBe('RateLimited');
       expect(platform.createPr.mock.calls).toBeEmpty();
     });
     it('should create PR if limit is reached but dashboard checked', async () => {
@@ -420,8 +439,9 @@ describe('workers/pr/index', () => {
           };
         }
       }
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
       expect(platform.createPr.mock.calls[0]).toMatchSnapshot([
         {
           prTitle: 'Update dependency dummy to v1.1.0',
@@ -438,8 +458,9 @@ describe('workers/pr/index', () => {
       config.timezone = 'some timezone';
       config.rebaseWhen = 'behind-base-branch';
       config.logJSON = await changelogHelper.getChangeLogJSON(config);
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
       expect(platform.createPr.mock.calls[0]).toMatchSnapshot([
         {
           prTitle: 'Update dependency dummy to v1.1.0',
@@ -456,9 +477,9 @@ describe('workers/pr/index', () => {
         throw new Error('Validation Failed (422)');
       });
       config.prCreation = 'status-success';
-      const { prBlockedBy, pr } = await prWorker.ensurePr(config);
-      expect(prBlockedBy).toBe('Error');
-      expect(pr).toBeUndefined();
+      const result = await prWorker.ensurePr(config);
+      isResultWithoutPr(result);
+      expect(result.prBlockedBy).toBe('Error');
     });
     it('should return null if waiting for not pending', async () => {
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.yellow);
@@ -466,9 +487,9 @@ describe('workers/pr/index', () => {
         Promise.resolve(new Date())
       );
       config.prCreation = 'not-pending';
-      const { prBlockedBy, pr } = await prWorker.ensurePr(config);
-      expect(prBlockedBy).toBe('AwaitingTests');
-      expect(pr).toBeUndefined();
+      const result = await prWorker.ensurePr(config);
+      isResultWithoutPr(result);
+      expect(result.prBlockedBy).toBe('AwaitingTests');
     });
     it('should not create PR if waiting for not pending with stabilityStatus yellow', async () => {
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.yellow);
@@ -477,9 +498,9 @@ describe('workers/pr/index', () => {
       );
       config.prCreation = 'not-pending';
       config.stabilityStatus = BranchStatus.yellow;
-      const { prBlockedBy, pr } = await prWorker.ensurePr(config);
-      expect(prBlockedBy).toBe('AwaitingTests');
-      expect(pr).toBeUndefined();
+      const result = await prWorker.ensurePr(config);
+      isResultWithoutPr(result);
+      expect(result.prBlockedBy).toBe('AwaitingTests');
     });
     it('should create PR if pending timeout hit', async () => {
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.yellow);
@@ -488,24 +509,28 @@ describe('workers/pr/index', () => {
       );
       config.prCreation = 'not-pending';
       config.stabilityStatus = BranchStatus.yellow;
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
     });
     it('should create PR if no longer pending', async () => {
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.red);
       config.prCreation = 'not-pending';
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
     });
     it('should create new branch if none exists', async () => {
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
     });
     it('should add assignees and reviewers to new PR', async () => {
       config.assignees = ['@foo', 'bar'];
       config.reviewers = ['baz', '@boo'];
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
       expect(platform.addAssignees).toHaveBeenCalledTimes(1);
       expect(platform.addAssignees.mock.calls).toMatchSnapshot();
       expect(platform.addReviewers).toHaveBeenCalledTimes(1);
@@ -551,8 +576,9 @@ describe('workers/pr/index', () => {
       });
       config.assignees = ['@foo', 'bar'];
       config.reviewers = ['baz', '@boo'];
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
       expect(platform.addAssignees).toHaveBeenCalledTimes(1);
       expect(platform.addReviewers).toHaveBeenCalledTimes(1);
     });
@@ -562,8 +588,9 @@ describe('workers/pr/index', () => {
       });
       config.assignees = ['@foo', 'bar'];
       config.reviewers = ['baz', '@boo'];
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
       expect(platform.addAssignees).toHaveBeenCalledTimes(1);
       expect(platform.addReviewers).toHaveBeenCalledTimes(1);
     });
@@ -571,8 +598,9 @@ describe('workers/pr/index', () => {
       config.assignees = ['bar'];
       config.reviewers = ['baz'];
       config.automerge = true;
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
       expect(platform.addAssignees).toHaveBeenCalledTimes(0);
       expect(platform.addReviewers).toHaveBeenCalledTimes(0);
     });
@@ -581,8 +609,9 @@ describe('workers/pr/index', () => {
       config.reviewers = ['baz'];
       config.automerge = true;
       config.assignAutomerge = true;
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
       expect(platform.addAssignees).toHaveBeenCalledTimes(1);
       expect(platform.addReviewers).toHaveBeenCalledTimes(1);
     });
@@ -591,8 +620,9 @@ describe('workers/pr/index', () => {
       config.assigneesSampleSize = 2;
       config.reviewers = ['baz', 'boo', 'bor'];
       config.reviewersSampleSize = 2;
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
       expect(platform.addAssignees).toHaveBeenCalledTimes(1);
       const assignees = platform.addAssignees.mock.calls[0][1];
       expect(assignees).toHaveLength(2);
@@ -608,24 +638,27 @@ describe('workers/pr/index', () => {
       config.assigneesSampleSize = 0;
       config.reviewers = ['baz', 'boo', 'bor'];
       config.reviewersSampleSize = 0;
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
       expect(platform.addAssignees).toHaveBeenCalledTimes(0);
       expect(platform.addReviewers).toHaveBeenCalledTimes(0);
     });
     it('should add and deduplicate additionalReviewers on new PR', async () => {
       config.reviewers = ['@foo', 'bar'];
       config.additionalReviewers = ['bar', 'baz', '@boo'];
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
       expect(platform.addReviewers).toHaveBeenCalledTimes(1);
       expect(platform.addReviewers.mock.calls).toMatchSnapshot();
     });
     it('should add and deduplicate additionalReviewers to empty reviewers on new PR', async () => {
       config.reviewers = [];
       config.additionalReviewers = ['bar', 'baz', '@boo', '@foo', 'bar'];
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
       expect(platform.addReviewers).toHaveBeenCalledTimes(1);
       expect(platform.addReviewers.mock.calls).toMatchSnapshot();
     });
@@ -635,10 +668,11 @@ describe('workers/pr/index', () => {
       config.automerge = true;
       config.schedule = ['before 5am'];
       config.logJSON = await changelogHelper.getChangeLogJSON(config);
-      const { pr } = await prWorker.ensurePr(config);
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
       expect(platform.updatePr.mock.calls).toMatchSnapshot();
       expect(platform.updatePr).toHaveBeenCalledTimes(0);
-      expect(pr).toMatchObject(existingPr);
+      expect(result.pr).toMatchObject(existingPr);
     });
     it('should return unmodified existing PR if only whitespace changes', async () => {
       const modifiedPr = JSON.parse(
@@ -649,9 +683,10 @@ describe('workers/pr/index', () => {
       config.automerge = true;
       config.schedule = ['before 5am'];
       config.logJSON = await changelogHelper.getChangeLogJSON(config);
-      const { pr } = await prWorker.ensurePr(config);
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
       expect(platform.updatePr).toHaveBeenCalledTimes(0);
-      expect(pr).toMatchObject(modifiedPr);
+      expect(result.pr).toMatchObject(modifiedPr);
     });
     it('should return modified existing PR', async () => {
       config.newValue = '1.2.0';
@@ -659,8 +694,9 @@ describe('workers/pr/index', () => {
       config.schedule = ['before 5am'];
       config.logJSON = await changelogHelper.getChangeLogJSON(config);
       platform.getBranchPr.mockResolvedValueOnce(existingPr);
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchSnapshot({
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchSnapshot({
         displayNumber: 'Existing PR',
         title: 'Update dependency dummy to v1.1.0',
       });
@@ -671,8 +707,9 @@ describe('workers/pr/index', () => {
         ...existingPr,
         title: 'wrong',
       });
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchSnapshot({
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchSnapshot({
         displayNumber: 'Existing PR',
         title: 'wrong',
       });
@@ -682,33 +719,36 @@ describe('workers/pr/index', () => {
       config.automergeType = 'branch';
       config.branchAutomergeFailureMessage = 'branch status error';
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.red);
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
     });
     it('should create PR if branch automerging failed', async () => {
       config.automerge = true;
       config.automergeType = 'branch';
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
       config.forcePr = true;
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
     });
     it('should return no PR if branch automerging not failed', async () => {
       config.automerge = true;
       config.automergeType = 'branch';
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.yellow);
       git.getBranchLastCommitTime.mockResolvedValueOnce(new Date());
-      const { prBlockedBy, pr } = await prWorker.ensurePr(config);
-      expect(prBlockedBy).toBe('BranchAutomerge');
-      expect(pr).toBeUndefined();
+      const result = await prWorker.ensurePr(config);
+      isResultWithoutPr(result);
+      expect(result.prBlockedBy).toBe('BranchAutomerge');
     });
     it('should return PR if branch automerging taking too long', async () => {
       config.automerge = true;
       config.automergeType = 'branch';
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.yellow);
       git.getBranchLastCommitTime.mockResolvedValueOnce(new Date('2018-01-01'));
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toBeDefined();
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toBeDefined();
     });
     it('should return no PR if stabilityStatus yellow', async () => {
       config.automerge = true;
@@ -716,14 +756,15 @@ describe('workers/pr/index', () => {
       config.stabilityStatus = BranchStatus.yellow;
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.yellow);
       git.getBranchLastCommitTime.mockResolvedValueOnce(new Date('2018-01-01'));
-      const { prBlockedBy, pr } = await prWorker.ensurePr(config);
-      expect(prBlockedBy).toBe('BranchAutomerge');
-      expect(pr).toBeUndefined();
+      const result = await prWorker.ensurePr(config);
+      isResultWithoutPr(result);
+      expect(result.prBlockedBy).toBe('BranchAutomerge');
     });
     it('handles duplicate upgrades', async () => {
       config.upgrades.push(config.upgrades[0]);
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
     });
     it('should create privateRepo PR if success', async () => {
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
@@ -731,8 +772,9 @@ describe('workers/pr/index', () => {
       config.privateRepo = false;
       config.logJSON = await changelogHelper.getChangeLogJSON(config);
       config.logJSON.project.repository = 'someproject';
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
       expect(platform.createPr.mock.calls[0]).toMatchSnapshot();
       existingPr.body = platform.createPr.mock.calls[0][0].prBody;
     });
@@ -742,8 +784,9 @@ describe('workers/pr/index', () => {
       config.prCreation = 'not-pending';
       config.artifactErrors = [{}];
       config.platform = PlatformId.Gitlab;
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toMatchObject({ displayNumber: 'New Pull Request' });
     });
 
     it('should trigger GitLab automerge when configured', async () => {
@@ -761,8 +804,9 @@ describe('workers/pr/index', () => {
     it('should create a PR with set of labels and mergeable addLabels', async () => {
       config.labels = ['deps', 'renovate'];
       config.addLabels = ['deps', 'js'];
-      const { pr } = await prWorker.ensurePr(config);
-      expect(pr).toBeDefined();
+      const result = await prWorker.ensurePr(config);
+      isResultWithPr(result);
+      expect(result.pr).toBeDefined();
       expect(platform.createPr.mock.calls[0][0]).toMatchObject({
         labels: ['deps', 'renovate', 'js'],
       });
diff --git a/lib/workers/pr/index.ts b/lib/workers/pr/index.ts
index 383aa0ead3ecdfb316376da4658a2da0f96ccea7..504fe36f2edd1327e7c69be1c99b7b297d96d98d 100644
--- a/lib/workers/pr/index.ts
+++ b/lib/workers/pr/index.ts
@@ -145,12 +145,12 @@ export function getPlatformPrOptions(
 }
 
 export type ResultWithPr = {
+  type: 'with-pr';
   pr: Pr;
-  prBlockedBy?: never;
 };
 
 export type ResultWithoutPr = {
-  pr?: never;
+  type: 'without-pr';
   prBlockedBy: PrBlockedBy;
 };
 
@@ -217,14 +217,14 @@ export async function ensurePr(
       logger.debug(`Branch tests failed, so will create PR`);
     } else {
       // Branch should be automerged, so we don't want to create a PR
-      return { prBlockedBy: 'BranchAutomerge' };
+      return { type: 'without-pr', prBlockedBy: 'BranchAutomerge' };
     }
   }
   if (config.prCreation === 'status-success') {
     logger.debug('Checking branch combined status');
     if ((await getBranchStatus()) !== BranchStatus.green) {
       logger.debug(`Branch status isn't green - not creating PR`);
-      return { prBlockedBy: 'AwaitingTests' };
+      return { type: 'without-pr', prBlockedBy: 'AwaitingTests' };
     }
     logger.debug('Branch status success');
   } else if (
@@ -232,7 +232,7 @@ export async function ensurePr(
     !existingPr &&
     dependencyDashboardCheck !== 'approvePr'
   ) {
-    return { prBlockedBy: 'NeedsApproval' };
+    return { type: 'without-pr', prBlockedBy: 'NeedsApproval' };
   } else if (
     config.prCreation === 'not-pending' &&
     !existingPr &&
@@ -257,6 +257,7 @@ export async function ensurePr(
           `Branch is ${elapsedHours} hours old - skipping PR creation`
         );
         return {
+          type: 'without-pr',
           prBlockedBy: 'AwaitingTests',
         };
       }
@@ -385,7 +386,7 @@ export async function ensurePr(
           noWhitespaceOrHeadings(stripEmojis(prBody))
       ) {
         logger.debug(`${existingPr.displayNumber} does not need updating`);
-        return { pr: existingPr };
+        return { type: 'with-pr', pr: existingPr };
       }
       // PR must need updating
       if (existingPrTitle !== newPrTitle) {
@@ -417,9 +418,7 @@ export async function ensurePr(
         });
         logger.info({ pr: existingPr.number, prTitle }, `PR updated`);
       }
-      return {
-        pr: existingPr,
-      };
+      return { type: 'with-pr', pr: existingPr };
     }
     logger.debug({ branch: branchName, prTitle }, `Creating PR`);
     // istanbul ignore if
@@ -439,7 +438,7 @@ export async function ensurePr(
           !config.isVulnerabilityAlert
         ) {
           logger.debug('Skipping PR - limit reached');
-          return { prBlockedBy: 'RateLimited' };
+          return { type: 'without-pr', prBlockedBy: 'RateLimited' };
         }
         pr = await platform.createPr({
           sourceBranch: branchName,
@@ -463,7 +462,7 @@ export async function ensurePr(
         )
       ) {
         logger.warn('A pull requests already exists');
-        return { prBlockedBy: 'Error' };
+        return { type: 'without-pr', prBlockedBy: 'Error' };
       }
       if (err.statusCode === 502) {
         logger.warn(
@@ -476,7 +475,7 @@ export async function ensurePr(
           await deleteBranch(branchName);
         }
       }
-      return { prBlockedBy: 'Error' };
+      return { type: 'without-pr', prBlockedBy: 'Error' };
     }
     if (
       config.branchAutomergeFailureMessage &&
@@ -514,7 +513,7 @@ export async function ensurePr(
       await addAssigneesReviewers(config, pr);
     }
     logger.debug(`Created ${pr.displayNumber}`);
-    return { pr };
+    return { type: 'with-pr', pr };
   } catch (err) {
     // istanbul ignore if
     if (
@@ -529,8 +528,8 @@ export async function ensurePr(
     logger.error({ err }, 'Failed to ensure PR: ' + prTitle);
   }
   if (existingPr) {
-    return { pr: existingPr };
+    return { type: 'with-pr', pr: existingPr };
   }
   // istanbul ignore next
-  return { prBlockedBy: 'Error' };
+  return { type: 'without-pr', prBlockedBy: 'Error' };
 }