Agents behaving badly

Agents were coming online one by one, having improvement, integrations were connecting, and Claude Code was doing most of the heavy lifting. Then Claude started to misbehave.

Agents behaving badly
Silly, Clumpsy bots

Background

Building was going well. Nine AI agents running on AWS Amplify, with API routes calling Bedrock (eu-west-1), SES, and third-party APIs.

Agents were coming online one by one, having improvement, integrations were connecting, and Claude Code was doing most of the heavy lifting. Then it started to misbehave.

Were there any env vars in Amplify before this, ask Claude?

30 plus environment variables erased

AWS Amplify's API replaces all environment variables in one call — it is not additive. So when Claude Code called update-app to add a new variable, it passed only the new one. Everything else was wiped. Agents that were working stopped working. All the API Secrets require to connect to MCPs and APIs were gone!

It took a while to work out why building at speed, asking Claude to write documentation when convenient, leaving it for another day when not.

The fix is straightforward once you know the cause. Three ways to prevent it:

1. Add a rule to CLAUDE.md

## AWS Amplify environment variables
NEVER update Amplify env vars directly with a single variable.
Always follow this sequence:
1. Read existing vars: `aws amplify get-app --app-id $APP_ID`
2. Extract the full environmentVariables block
3. Merge the new variable into the existing set
4. Write the complete set back with `aws amplify update-app`

2. Use a helper script Claude Code calls instead

#!/bin/bash
# add-env-var.sh — safe Amplify env var update
APP_ID=$1
KEY=$2
VALUE=$3

EXISTING=$(aws amplify get-app --app-id $APP_ID \
  --query 'app.environmentVariables' --output json)

aws amplify update-app --app-id $APP_ID \
  --environment-variables \
  "$(echo $EXISTING | jq -r 'to_entries | map("\(.key)=\(.value)") | join(",")'),${KEY}=${VALUE}"

Then in CLAUDE.md: always use add-env-var.sh, never call update-app directly.

3. Use branch-level variables — same behaviour, but scoping per branch and using a script makes the read-merge-write pattern easier to enforce.

The CLAUDE.md rule is the most reliable fix. It constrains the behaviour permanently, regardless of how the task is phrased in a future session.

Nine Agents, Now Hopefully Still Running

Once we recovered — and added the CLAUDE.md rule — the nine agents came back online. Or most of them. There may still be an environment variable missing somewhere.

Video. Write the scene scripts, upload background images, hit Render. HeyGen generates the avatar video; Publish pushes it to YouTube.

Ideas. Ten editable video ideas. Generate rewrites them with Bedrock; Create Script writes a full seven-scene script straight into the matching Video slot.

Daily Prospects. Reads the last 24 hours of Gmail every morning, ranks contacts by likelihood, and emails a formatted action table.

Daily Briefing. FileDone metrics, Gmail digest, company research on external senders, and a three-item action list — saved to Postgres, comparable day-to-day.

Enrolment. Stripe purchase triggers Ghost membership, MCP API key creation, and welcome email — all within five minutes, via SQS.

Compliance. UK filing deadlines from FileDone — Companies House, HMRC, VAT, PAYE — with green/amber/red badges. Monday digest emailed to the configured recipient.

Tasks. Action items from other agents land here automatically. One-click Complete link with a signed JWT — works from a forwarded email, no login needed.

Chatbot. Freemium gate on every workshop page. Anonymous visitors get FAQ answers; members get Bedrock responses with Stripe checkout tools.

Billing. Actual spend per agent, expandable per service — visible to the administrator.


The architecture and agent configuration are covered in detail in the Agentic CEO workshop.