Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Professional English for Developers  Module 5 – Emails and chat

Apologies, bad news and escalations

Send bad news early with what happened, the impact, the plan and the next update, apologise once and specifically, and escalate with evidence and an ask.

  • Advanced
  • 25 minutes
  • Examples run with Node.js 24.21.0 and quickjs 0.32.0
  • By MySmartCoPilot
Free core, Pro depth: 9 of 25 minutes free
Free: Bad news goes out early, in four parts · One apology, specific, then the fix. With a pass: 3 in-depth parts and 3 interview answers, about 16 minutes.

What you will learn

  • Report bad news early, with what happened, who is affected, the plan and the next update
  • Rewrite stacked or vague apologies as one specific apology followed by the fix
  • Write an escalation that names the blocker, what you tried and the decision you need
  • Schedule incident updates for stakeholders and say in each when the next one comes

Before you start

What you’ll learn · Before you start

What you will learn

  • Report bad news early, with what happened, who is affected, the plan and the next update
  • Rewrite stacked or vague apologies as one specific apology followed by the fix
  • Write an escalation that names the blocker, what you tried and the decision you need
  • Schedule incident updates for stakeholders and say in each when the next one comes

Before you start

On this page

Three emails told one client that a release would slip. The one written in four parts had everything a reader needs, and the other two had one part between them, along with three apologies, a guess at the cause and the word “soon” for the next update.

Bad news goes out early, with four parts: what happened, who is affected and how, what you are doing, and when the next update comes. An apology works when there is only one, and it names what went wrong. escalation: Asking someone with more authority to decide or to unblock work, after your own request and your reminders have not worked. ask the person who can decide, with what you tried. Incident updates repeat the four parts on a schedule that you keep.

Bad news goes out early, in four parts

On Thursday at 12:00 Eastern Time, Kavya’s final tests found that Friday’s release would not fix the CSV export for every account. She could write to Daniel, the client, at once, or hope for a fix by Friday and tell him then. A day of notice is worth more to him than a day of hope, so she wrote at once, in four parts, with every time in his zone:

Interactive · stage by stage Building a bad-news email in four parts Step through the email Kavya sent a day before the release. Each step adds one part and says what it gives Daniel.
Building a bad-news email in four parts, step 6 of 6. Showing What happened (Friday moves to Tuesday), Who is affected, and how (2 of 30 accounts), What we are doing (fix today, test Monday), One apology (1 sentence: the delay), The next update (Monday 17:00 ET). In focus: The next update.What happenedFriday moves to TuesdayWho is affected, and how2 of 30 accountsWhat we are doingfix today, test MondayOne apology1 sentence: the delayThe next updateMonday 17:00 ET

The drawing shows the whole scene; its 6 steps are listed below.

Every step as text
  1. Write it the day you know. Thursday 12:00 Eastern Time. The final tests have just found the problem, and the release is on Friday. Kavya writes now, a day before, instead of hoping the fix arrives in time.
  2. What happened. "Friday's release of the CSV export fix is moving to Tuesday." The news and the new date come first, so Daniel knows the one thing that changes for him before he reads anything else.
  3. Who is affected, and how. Exports for 2 of the 30 merchant accounts still show the next day's date after 20:00, and the finance team can keep using the current export for the other 28. Numbers tell Daniel how big the problem is.
  4. What we are doing. "We are fixing the date rule for those two accounts today and will test it on Monday." What the team knows, what it is doing and when, with no guess about why the rule failed.
  5. One apology. "I'm sorry for the delay." One sentence, for the thing that affects Daniel, near the end, after he has the facts. No boilerplate and no second apology.
  6. The next update. "I will send the next update by Monday 17:00 Eastern Time." Daniel knows when he will hear more, in his own zone, so he does not have to chase Kavya for it.

Each part answers a question the reader would otherwise send back: what changed, does it affect me, what are you doing, and when will I hear more. The order matters too. The news comes first, as Microsoft’s style guide asks for anything a reader scans: “Lead with what’s most important.” Say only what you know: a guess about the cause, such as “probably the database team”, has to be taken back in the next update if it is wrong.

The program checks Kavya’s email and two others that told Daniel the same news: one sent late, one in a panic.

Three emails with the same bad news, checked for the four parts JavaScript · badnews/bad_news_check.mjs
// Three emails that tell a client the same bad news, checked for the four parts of a bad-news message (what happened,
// who is affected and how, what we are doing, and when the next update comes, with a time and a zone) and for three
// slips: stacked or boilerplate apologies, guessing at a cause, and times nobody can plan around.

const PARTS = [
  ['what happened', /\b(?:is|has been) (?:delayed|moving|moved)\b|\b(?:moves|failed|missed|found|is down|will not)\b/i],
  ['who is affected, and how', /\b\d+ of (?:your )?\d+\b|\baffect\w*\b|\bcan keep using\b|\bcannot use\b/i],
  ['what we are doing', /\b(?:we are|we're) (?:fixing|testing|replacing|rolling|checking)\b|\bwe will (?:fix|test|release)\b/i],
  ['the next update, with a time and zone', /\bnext update\b[^.?!]*\b\d{1,2}:\d{2}\b[^.?!]*\b(?:UTC|IST|ET|Eastern Time)\b/i],
];
const APOLOGY = /\b(?:sorry|apologi[sz]e|apologies)\b/gi;
const BOILERPLATE = /\bsorry for (?:the|any) inconvenience(?: caused)?\b/i;
const GUESS = /\b(?:probably|maybe|might have been|we think it was|seems to be)\b/i;
const VAGUE = /\b(?:soon|shortly|some issues|unforeseen|might get delayed)\b/gi;

function check(text) {
  const missing = PARTS.filter(([, re]) => !re.test(text)).map(([name]) => name);
  const flags = [];
  const apologies = (text.match(APOLOGY) ?? []).length;
  if (apologies > 1) flags.push(`${apologies} apologies: say sorry once, for something specific`);
  if (BOILERPLATE.test(text)) flags.push(`"${text.match(BOILERPLATE)[0]}" is boilerplate: name what you are sorry for`);
  if (GUESS.test(text)) flags.push(`"${text.match(GUESS)[0]}": a guess at the cause; say what you know`);
  for (const m of text.matchAll(VAGUE)) flags.push(`"${m[0]}" tells the reader nothing they can plan with`);
  return { missing, flags };
}

const EMAILS = [
  ['The late, vague email (Friday 15:00 Eastern Time)', `Hi Daniel,
We are facing some issues with the release and it might get delayed. Will update soon.
Regards,
Kavya`],
  ['The panicked email (Thursday 18:00 Eastern Time)', `Hi Daniel,
Extremely sorry for the inconvenience caused!! We deeply apologise. Due to unforeseen technical challenges, which were probably caused by the database team, the release is delayed. Sorry again, we are trying our best.
Regards,
Kavya`],
  ['The four-part email (Thursday 12:00 Eastern Time)', `Hi Daniel,
Friday's release of the CSV export fix is moving to Tuesday. Our final tests found that exports for 2 of your 30 merchant accounts still show the next day's date after 20:00. Your finance team can keep using the current export, which is correct for the other 28 accounts. We are fixing the date rule for those two accounts today and will test it on Monday. I'm sorry for the delay. I will send the next update by Monday 17:00 Eastern Time.
Thanks,
Kavya`],
];

for (const [name, text] of EMAILS) {
  const { missing, flags } = check(text);
  console.log(`${name}: ${PARTS.length - missing.length} of ${PARTS.length} parts`);
  for (const m of missing) console.log(`  missing: ${m}`);
  for (const f of flags) console.log(`  flag: ${f}`);
}

Output

The late, vague email (Friday 15:00 Eastern Time): 0 of 4 parts
  missing: what happened
  missing: who is affected, and how
  missing: what we are doing
  missing: the next update, with a time and zone
  flag: "some issues" tells the reader nothing they can plan with
  flag: "might get delayed" tells the reader nothing they can plan with
  flag: "soon" tells the reader nothing they can plan with
The panicked email (Thursday 18:00 Eastern Time): 1 of 4 parts
  missing: who is affected, and how
  missing: what we are doing
  missing: the next update, with a time and zone
  flag: 3 apologies: say sorry once, for something specific
  flag: "sorry for the inconvenience caused" is boilerplate: name what you are sorry for
  flag: "probably": a guess at the cause; say what you know
  flag: "unforeseen" tells the reader nothing they can plan with
The four-part email (Thursday 12:00 Eastern Time): 4 of 4 parts

Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node bad_news_check.mjs

The four-part email has every part and no flags. The late one has none of the parts, and “soon” and “some issues” tell Daniel nothing he can plan with. The panicked one says only what happened, and buries it under three apologies, a boilerplate phrase and a guess that blames another team.

Key idea

Send bad news the day you know it, in four parts: what happened, who is affected and how, what you are doing, and when the next update comes.

Checkpoint

Check: Bad news early, in four parts

  1. Question 1 of 2 Kavya learns on Thursday that Friday's release will slip. Which first sentence should her email to the client have?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Friday's release of the CSV export fix is moving to Tuesday.

    Lead with what happened and the new date: "Friday's release of the CSV export fix is moving to Tuesday."

  2. Question 2 of 2 You suspect that another team's change caused the bug, but nobody has confirmed it. What goes in the email to the client?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Only what you know, with what fails, for whom, what you are doing and when the next update comes

    Say what you know, and leave the cause out until it is confirmed.

One apology, specific, then the fix

“Extremely sorry for the inconvenience caused!! We deeply apologise.” Neither sentence says what the writer is sorry for, and three apologies in one email make the reader wonder how bad things really are. An apology works when there is only one, it names what went wrong, and it comes after the facts, followed by the fix:

Instead of Write Why
Sorry for the inconvenience caused. I’m sorry for the delay. it names what affects the reader
We deeply apologise. Sorry again. I’m sorry I missed the 17:00 IST deadline for the test report. one apology, for a specific miss
Sorry if you felt the update was late. I’m sorry the update was late. the condition shifts the fault to the reader
Sorry to bother you, but … Could you check the export by Friday? asking is not a mistake

Say I’m sorry when the miss is yours and we’re sorry when it is the team’s. Then move on to the new date and the plan, because the fix is what the reader will act on. Stacked apologies push that plan down the page.

The rest of this lesson uses the same parts for harder messages. Blameless wording describes what the system did, not who made it fail. Escalations ask someone with more authority to decide. And incident updates repeat the four parts on a schedule, saying in each when the next one comes.

Checkpoint

Check: One specific apology, then the fix

  1. Question 1 of 2 Which apology follows the lesson?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: I'm sorry I missed the 17:00 IST deadline for the test report.

    Apologise once, for something specific: "I'm sorry I missed the 17:00 IST deadline for the test report."

  2. Question 2 of 2 Why is "Sorry if you felt the update was late" a weak apology?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: The condition shifts the fault to the reader's feelings instead of naming the miss

    Drop the "if": "I'm sorry the update was late."

Blameless wording: systems and decisions, not people, line by line Pro: opens with a Pro, Premium or Ultimate pass

When something breaks, the first draft of the story usually names who did it. This part rewrites an incident timeline so that it names what to fix instead, checks every line, and shows where the passive voice is the right choice.

In this part:

  • A draft timeline that blames, rewritten line by line
  • Where the passive voice is the right choice

1 runnable example (JavaScript) · about 3 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Escalating a blocker: the email before and after, and who is copied Pro: opens with a Pro, Premium or Ultimate pass

An escalation is a request to someone with more authority, made after the direct ask and the reminders have not worked. This part checks one escalation before and after a rewrite, and lets you decide who receives yours.

In this part:

  • The escalation email, checked part by part
  • Who gets it, and who is copied

1 runnable example (JavaScript) · about 7 minutes

Opening this part with your pass…Pro part. It opens with the same pass as the part above.

Incident updates on a schedule: an outage minute by minute, timed Pro: opens with a Pro, Premium or Ultimate pass

During an outage, stakeholder: A person or a group affected by a project or an incident, or with a say in it, such as a client, a manager or a support team. need the four parts again and again, at times they can count on. This part follows one outage minute by minute, times two teams’ messages against an open incident guide, and ends with an exercise.

In this part:

  • The cadence of an open incident guide, measured
  • The tense of each part, and the times in it
  • Write the first update and the resolution of an incident
    • Results of the sample tests
  • Three rules to keep from the parts on blame, escalation and updates

1 diagram · 1 runnable example (JavaScript) · 1 exercise with sample tests · about 6 minutes

Opening this part with your pass…Pro part. It opens with the same pass as the part above.

Practise: a bad-news email in four parts

The exercise holds an email that tells a client’s QA lead about a late build, written in a panic. Rewrite it until the sample tests pass:

Exercise · Medium · JavaScript

Rewrite a bad-news email in four parts

Kavya's team promised Lena, the QA lead of a client in Berlin, a new build of the mobile app by Wednesday 12:00 UTC. On Tuesday the final tests found that the app crashes on Android 14 when a user opens a saved card, so the build moves to Friday. Lena's testers can keep using build 2.3 for everything except saved cards. The team is fixing the crash today and will test it on Thursday, and Kavya will send the next update by Thursday 16:00 UTC.

email.mjs holds the email Kavya first wrote. Rewrite it, inside the quotes, so that it has:

  • what happened in the first sentence: the build, and its new day;
  • who is affected, and how: Android 14, and what the testers can keep using;
  • what you are doing: We are fixing … or We will test …;
  • one apology, for something specific, and no inconvenience caused;
  • the next update with a time and its zone;
  • no guess at the cause (probably, maybe, might), no soon or some issues, no sentence over 25 words, and a closing line before the name.

Starter code · email.mjs

// Rewrite Kavya's email to Lena in four parts. Keep the greeting as the first line and the closing line and the name
// as the last two, separated by \n.
export const email =
  'Hi Lena,\n' +
  'Extremely sorry for the inconvenience caused!! Due to some unforeseen issues, which are probably in the payment ' +
  'SDK, the build might get delayed. We deeply apologise and will update you soon.\n' +
  'Regards,\n' +
  'Kavya';
The sample tests · email.test.mjs
import { test, assert } from 'mysmartcopilot:test';
import { email } from './email.mjs';

// The lesson's four parts of bad news, and its apology rules.
const lines = email.split('\n');
const body = lines.slice(1, -2).join(' ');
const sentences = body.split(/(?<=[.!?])\s+/).filter(Boolean);
const APOLOGY = /\b(?:sorry|apologi[sz]e|apologies)\b/gi;
const CLOSING = /^(?:Thanks|Thank you|Many thanks|Regards|Best regards|Kind regards|Best),$/;

test('the first sentence says what happened: the build and its new day', () => {
  const first = sentences[0] ?? '';
  assert.ok(/\bbuild\b/i.test(first) && /\bFriday\b/.test(first), `start with the news, the build and Friday: "${first}"`);
});

test('it says who is affected, and how', () => {
  assert.ok(/\bAndroid 14\b/.test(body), 'say which phones are affected: Android 14');
  assert.ok(/\b(?:build 2\.3|can keep)\b/i.test(body), 'say what the testers can keep using: build 2.3');
});

test('it says what the team is doing', () => {
  assert.ok(/\b(?:we are|we're) (?:fixing|testing)\b|\bwe will (?:fix|test)\b/i.test(body), 'say what you are doing: We are fixing …');
});

test('it gives the next update a time and a zone', () => {
  assert.ok(/\bnext update\b[^.?!]*\b\d{1,2}:\d{2}\b[^.?!]*\b(?:UTC|CET|CEST|IST)\b/i.test(body), 'say when the next update comes, with a time and its zone');
});

test('it apologises once, for something specific', () => {
  const n = (body.match(APOLOGY) ?? []).length;
  assert.equal(n, 1, `${n} apologies: say sorry once`);
  assert.ok(!/\binconvenience\b/i.test(body), '"inconvenience caused" is boilerplate: say what you are sorry for');
});

test('no guesses, no vague words, short sentences and a closing line', () => {
  assert.ok(!/\b(?:probably|maybe|might)\b/i.test(body), 'say what you know, not what the cause might be');
  assert.ok(!/\b(?:soon|some issues|unforeseen)\b/i.test(body), 'give facts and times, not "soon" or "some issues"');
  assert.ok(!/!!/.test(email), 'no "!!"');
  for (const s of sentences) {
    const n = s.split(/\s+/).length;
    assert.ok(n <= 25, `${n} words: "${s}"`);
  }
  assert.ok(CLOSING.test(lines.at(-2) ?? ''), 'end with a closing line, such as "Thanks,", before the name');
});
A hint

Start with the news itself: "The new app build is moving from Wednesday to Friday." Then one sentence each for the crash, what the testers can use, the fix, the apology and the next update.

The sample tests run on this device, in your browser (QuickJS): nothing is sent to mysmartcopilot.com. The first run downloads JavaScript (about 0.6 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Then try the questions on bad news and apologies:

Practice that adapts to you

Practise this lesson

6 questions about 5 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 6 Which parts does a bad-news message need?

    Choose every answer that is right.

    Show the answer: Question 1 of 6

    Answer:

    • when the next update comes, with a time and a zone
    • who is affected, and how
    • what happened
    • what you are doing

    What happened, who is affected and how, what you are doing, and the next update with a time and a zone.

  2. Question 2 of 6 When do you send bad news about a date you will miss?

    Choose one answer.

    Show the answer: Question 2 of 6

    Answer: The day you know, even if a fix might still arrive in time

    Send it the day you know it, with the four parts.

  3. Question 3 of 6 Which sentence tells a client how big a problem is?

    Choose one answer.

    Show the answer: Question 3 of 6

    Answer: Exports for 2 of your 30 merchant accounts still show the next day's date after 20:00.

    Give numbers, not adjectives, for who is affected and how.

  4. Question 4 of 6 Where does the apology go in a bad-news email?

    Choose one answer.

    Show the answer: Question 4 of 6

    Answer: After the facts, once, followed by the fix

    One apology, after the facts, then the new date and the plan.

  5. Question 5 of 6 "Sorry to bother you, but could you check the export by Friday?" What should change?

    Choose one answer.

    Show the answer: Question 5 of 6

    Answer: Drop the apology, because asking is not a mistake

    Apologise for mistakes, not for asking.

  6. Question 6 of 6 The deadline for the test report was yours, and you missed it. Which apology fits?

    Choose one answer.

    Show the answer: Question 6 of 6

    Answer: I'm sorry I missed the 17:00 IST deadline for the test report.

    Say I'm sorry when the miss is yours, name it, and move to the fix.

Interview questions

Warm-up (fresher to mid-level): What makes an apology in a work email specific?

It names what went wrong and how it affects the reader, once: “I’m sorry I missed the 17:00 IST deadline for the test report”, not “sorry for the inconvenience caused”. It comes after the facts, and the fix follows it at once: the new time, and what you are doing so that it does not happen again. One apology is enough.

Three longer questions of this module’s bank build on this lesson:

  1. Fresher to mid

    You promised a client a fix by Friday. On Thursday you learn it will take until Tuesday, because a library you depend on has a bug. Write the first three sentences of your email to the client, and explain each one.

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Mid to senior

    Your launch is next Monday, and the team that must approve a firewall change has not answered for four days, despite two reminders. When do you escalate, to whom, and what does your message say?

    Model answer, Pro. First step and follow-ups

  3. Mid to staff

    During a payments outage you are asked to keep business stakeholders informed while the engineers fix it. What do your first three messages say, and when does each one go out?

    Model answer, Pro. First step and follow-ups

Key takeaways

  • Send bad news the day you know it, with what happened, who is affected and how, what you are doing, and the next update with a time and a zone.
  • Apologise once, for something specific, after the facts, and move straight to the fix and the new date.
  • Say only what you know: a guess about the cause, or a word such as “soon”, gives the reader nothing to plan with.

Terms in this lesson

blameless postmortem
A review of an incident that looks for the causes in systems and decisions rather than in people, assuming that everyone acted with good intentions on what they knew at the time.
escalation
Asking someone with more authority to decide or to unblock work, after your own request and your reminders have not worked.
stakeholder
A person or a group affected by a project or an incident, or with a say in it, such as a client, a manager or a support team.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.