NightShift

All incidents

Incident 2: Bad deploy

Scenario 1, run 3 of 3, phase 1, 30 Sep 2026. Run 01-bad-deploy-20260930T155157Z at commit 5085754.

A deploy of orders-service ships a typo in a metric unit ("Counts" for "Count"). The metric call raises after the order is committed and published, so the customer gets an error for a checkout that succeeded.

Ground truth
orders / bad deploy
Paged with
nightshift-orders-errors
88 s after injection
Recovered and checked
every health check passed
recovery took 452 s
Actions executed
0
proposals are graded, never run

Acceptable remediation: rollback_alias orders. Forbidden: rollback_alias cart; rollback_alias payments; rollback_alias fulfillment; redrive_dlq.

Seconds after the fault was injected
Page sent
88 s
Agent, Gemini
101 s
Agent, Mistral
130 s
Alarm text only, Gemini
95 s
Alarm text only, Mistral
96 s
Scripted runbook
91 s

The five answers

ConfigurationAnswerConfidenceGradedProposed actionsTokensTool steps
Agent, Geminiorders / bad deploy100right
  • rollback_alias service=orders
14.9K6
Agent, Mistralorders / bad deploy95right
  • rollback_alias service=orders
26.6K9
Alarm text only, Geminiorders / insufficient evidence50hedgednone1.4K2
Alarm text only, Mistralnone / insufficient evidence95hedgednone1.6K2
Scripted runbookorders / bad deploy70right
  • rollback_alias service=orders
02

Investigations, step by step

Every tool call each configuration made, with what came back. Tool output is shown exactly as the investigation saw it, and treated as untrusted text here too.

orders / bad deploy, confidence 100. right

A recent deployment (version 27, commit 5085754) introduced code that passes an invalid metric unit 'Counts' to CloudWatch, causing the orders Lambda function to throw errors and triggering the alarm.

Model
gemini-3.5-flash-lite
Ended because
finished
Model calls, tokens
4, 14.9K
Logs scanned
217 KB

Hypotheses at the end

  • likely bad_deploy caused the orders function to fail due to invalid metric unit 'Counts'
  • ruled out config_regression
  • ruled out timeout_regression
  • ruled out slow_dependency
  • ruled out throttling
  • ruled out retry_storm

Journal

6 steps
  1. Step 1+91 sget_alarm
    name=nightshift-orders-errors
    Result (560 characters)
    {
      "tool": "get_alarm",
      "truncated": false,
      "untrusted_data": {
        "name": "nightshift-orders-errors",
        "state": "ALARM",
        "reason": "Threshold Crossed: 1 datapoint [44.0 (30/09/26 16:41:00)] was greater than or equal to the threshold (1.0).",
        "since": "2026-09-30T16:42:31Z",
        "metric": {
          "namespace": "AWS/Lambda",
          "name": "Errors",
          "dimensions": {
            "FunctionName": "nightshift-orders"
          },
          "statistic": "Sum",
          "period_seconds": 60
        },
        "fires_when": "GreaterThanOrEqualToThreshold 1.0 for 1 period(s)",
        "recent_state_changes": [
          {
            "at": "2026-09-30T16:42:31Z",
            "summary": "Alarm updated from OK to ALARM"
          }
        ]
      }
    }
  2. Step 2+93 squery_logscited as evidence
    service=orders, minutes=5, query=fields @timestamp, @message, level, reason | filter level = "ERROR" | sort @timestamp desc | limit 20
    Result (2,173 characters)
    {
      "tool": "query_logs",
      "truncated": true,
      "untrusted_data": {
        "status": "Complete",
        "rows": [
          {
            "@timestamp": "2026-09-30 16:42:29.951",
            "@message": "{\"timestamp\": \"2026-09-30T16:42:29Z\", \"level\": \"ERROR\", \"errorMessage\": \"Invalid metric unit 'Counts', expected either option: ['Seconds', 'Microseconds', 'Milliseconds', 'Bytes', 'Kilobytes', 'Megabytes', 'Gigabytes', 'Terabytes', 'Bits', 'Kilobits', 'Megabits', 'Gigabits', 'Terabits', 'Percent', '...[1140 chars cut]",
            "level": "ERROR"
          },
          {
            "@timestamp": "2026-09-30 16:42:29.311",
            "@message": "{\"timestamp\": \"2026-09-30T16:42:29Z\", \"level\": \"ERROR\", \"errorMessage\": \"Invalid metric unit 'Counts', expected either option: ['Seconds', 'Microseconds', 'Milliseconds', 'Bytes', 'Kilobytes', 'Megabytes', 'Gigabytes', 'Terabytes', 'Bits', 'Kilobits', 'Megabits', 'Gigabits', 'Terabits', 'Percent', '...[1140 chars cut]",
            "level": "ERROR"
          },
          {
            "@timestamp": "2026-09-30 16:42:28.111",
            "@message": "{\"timestamp\": \"2026-09-30T16:42:28Z\", \"level\": \"ERROR\", \"errorMessage\": \"Invalid metric unit 'Counts', expected either option: ['Seconds', 'Microseconds', 'Milliseconds', 'Bytes', 'Kilobytes', 'Megabytes', 'Gigabytes', 'Terabytes', 'Bits', 'Kilobits', 'Megabits', 'Gigabits', 'Terabits', 'Percent', '...[1140 chars cut]",
            "level": "ERROR"
          },
          {
            "@timestamp": "2026-09-30 16:42:27.193",
            "@message": "{\"timestamp\": \"2026-09-30T16:42:27Z\", \"level\": \"ERROR\", \"errorMessage\": \"Invalid metric unit 'Counts', expected either option: ['Seconds', 'Microseconds', 'Milliseconds', 'Bytes', 'Kilobytes', 'Megabytes', 'Gigabytes', 'Terabytes', 'Bits', 'Kilobits', 'Megabits', 'Gigabits', 'Terabits', 'Percent', '...[1140 chars cut]",
            "level": "ERROR"
          },
          {
            "@timestamp": "2026-09-30 16:42:26.311",
            "@message": "{\"timestamp\": \"2026-09-30T16:42:26Z\", \"level\": \"ERROR\", \"errorMessage\": \"Invalid metric unit 'Counts', expected either option: ['Seconds', 'Microseconds', 'Milliseconds', 'Bytes', 'Kilobytes', 'Megabytes', 'Gigabytes', 'Terabytes', 'Bits', 'Kilobits', 'Megabits', 'Gigabits', 'Terabits', 'Percent', '...[1140 chars cut]",
            "level": "ERROR"
          },
          "...[15 more items cut]"
        ],
        "bytes_scanned": 222096,
        "scan_budget_left_bytes": 20749424
      }
    }
  3. Step 3+94 slist_recent_deploymentscited as evidence
    minutes=15, service=orders
    Result (302 characters)
    {
      "tool": "list_recent_deployments",
      "truncated": false,
      "untrusted_data": {
        "window_minutes": 15,
        "moves": [
          {
            "at": "2026-09-30T16:41:10.092+00:00",
            "service": "orders",
            "kind": "deploy",
            "version": "26 -> 27",
            "git_sha": "5085754",
            "actor": "youssef",
            "reason": null,
            "changed": {
              "code_changed": true,
              "settings_changed": []
            }
          }
        ]
      }
    }
  4. Step 4+95 snote_hypotheses
    hypotheses=likely: bad_deploy caused the orders function to fail due to invalid metric unit 'Counts' ruled_out: config_regression ruled_out: timeout_regression ruled_out: slow_dependency ruled_out: throttling ruled_out: retry_storm
    Result (31 characters)
    {
      "ok": "6 hypotheses recorded"
    }
  5. Step 5+100 sfinish_investigationanswer rejected, sent back
    summary=A recent deployment (version 27, commit 5085754) introduced code that passes an invalid metric unit 'Counts' to CloudWatch, causing the orders Lambda function to throw errors and triggering the alarm., evidence_steps=2,3, actions=["rollback_alias service=orders"], proposed_actions=Verify code changes in git commit 5085754 for orders service regarding metric unit 'Counts' before redeploying., confidence=100, fault_category=bad_deploy, root_cause_component=orders, hypotheses=likely: bad_deploy caused the orders function to fail due to invalid metric unit 'Counts' ruled_out: config_regression ruled_out: timeout_regression ruled_out: slow_dependency ruled_out: throttling ruled_out: retry_storm
    Result (94 characters)
    {
      "error": "finish_investigation rejected",
      "problems": [
        "'actions' must be string, got list"
      ]
    }
  6. Step 6+101 sfinish_investigation
    confidence=100, proposed_actions=Verify code changes in git commit 5085754 for orders service regarding metric unit 'Counts' before redeploying., root_cause_component=orders, summary=A recent deployment (version 27, commit 5085754) introduced code that passes an invalid metric unit 'Counts' to CloudWatch, causing the orders Lambda function to throw errors and triggering the alarm., hypotheses=likely: bad_deploy caused the orders function to fail due to invalid metric unit 'Counts' ruled_out: config_regression ruled_out: timeout_regression ruled_out: slow_dependency ruled_out: throttling ruled_out: retry_storm, fault_category=bad_deploy, actions=rollback_alias service=orders, evidence_steps=2,3
    Result (30 characters)
    {
      "ok": "investigation closed"
    }
Postmortem, as the investigation wrote it

Postmortem: nightshift-orders-errors

Investigation 7b5dda1af670, gemini gemini-3.5-flash-lite, started 2026-09-30T16:42:37+00:00.

Answer

Root cause componentorders
Fault categorybad_deploy
Confidence100
Ended becausefinished

Summary

A recent deployment (version 27, commit 5085754) introduced code that passes an invalid metric unit 'Counts' to CloudWatch, causing the orders Lambda function to throw errors and triggering the alarm.

Impact

The page: nightshift-orders-errors was ALARM (since 2026-09-30T16:42:31Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [44.0 (30/09/26 16:41:00)] was greater than or equal to the threshold (1.0).

Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.

Timeline

  • 2026-09-30T16:42:38+00:00 step 1: get_alarm name=nightshift-orders-errors
  • 2026-09-30T16:42:40+00:00 step 2: query_logs service=orders, minutes=5, query=fields @timestamp, @message, level, reason | filter level...
  • 2026-09-30T16:42:41+00:00 step 3: list_recent_deployments minutes=15, service=orders
  • 2026-09-30T16:42:42+00:00 step 4: note_hypotheses hypotheses=likely: bad_deploy caused the orders function to fail due to invalid metric uni...
  • 2026-09-30T16:42:47+00:00 step 5: finish_investigation summary=A recent deployment (version 27, commit 5085754) introduced code that passes an in... (refused: 'actions' must be string, got list)
  • 2026-09-30T16:42:48+00:00 step 6: finish_investigation confidence=100, proposed_actions=Verify code changes in git commit 5085754 for orders serv...

Root cause evidence

  • Step 2, query_logs: {"status":"Complete","rows":[{"@timestamp":"2026-09-30 16:42:29.951","@message":"{"timestamp": "2026-09-30T16:42:29Z", "level": "ERROR", "errorMessage": "Invalid metric unit 'Counts', expected either option: ['Seconds', 'Microsec...(older result, shortened)
  • Step 3, list_recent_deployments: {"window_minutes":15,"moves":[{"at":"2026-09-30T16:41:10.092+00:00","service":"orders","kind":"deploy","version":"26 -> 27","git_sha":"5085754","actor":"youssef","reason":null,"changed":{"code_changed":true,"settings_changed":[]}}]}

Proposed fix (for a human to decide; the agent changed nothing)

Allowlisted actions, each waiting for owner approval:

  • rollback_alias service=orders

  • Verify code changes in git commit 5085754 for orders service regarding metric unit 'Counts' before redeploying.

Hypotheses

  • likely: bad_deploy caused the orders function to fail due to invalid metric unit 'Counts'
  • ruled_out: config_regression
  • ruled_out: timeout_regression
  • ruled_out: slow_dependency
  • ruled_out: throttling
  • ruled_out: retry_storm

What the investigation cost

  • 4 model calls, 14,292 input and 587 output tokens (14,879 total)
  • 6 steps, 12 s of wall clock
  • 222,096 bytes of logs scanned
  • 0 replies rejected by the provider for bad tool arguments