This is a submission for DEV's Summer Bug Smash: Smash Stories powered by Sentry.
I spent a week deploying a CrewAI agent to AWS Bedrock AgentCore. The SDK wasn't on PyPI. The error messages were 200 OKs. The container crashed without logs. And the naming regex rejected hyphens without telling me why.
This is the full debugging trail. Every failure was silent. Every fix required reading source code nobody documented.
Table of Contents
- The Project
- Failure 1: The SDK That Doesn't Exist on PyPI
- Failure 2: The 200 OK That Means Failure
- Failure 3: The Container That Crashed With No Logs
- Failure 4: The Naming Regex Nobody Documented
- The Two-Client Split Nobody Mentions
- What I Learned
The project
I built a resume-tailoring AI agent with CrewAI and Amazon Bedrock. It takes a job description, analyzes your resume, identifies gaps, and rewrites bullet points to match what the role actually needs.
Locally it worked perfectly. CrewAI orchestrates the agents, Bedrock Nova Pro handles the LLM calls, and the output is solid. Deploying it to production was the problem.
AWS launched Bedrock AgentCore in June 2026 as a managed runtime for AI agents. You containerize your agent, push the image, and AgentCore handles scaling, memory, and invocation. Sounds simple.
It was not simple.
Failure 1: The SDK that doesn't exist on PyPI
The docs say to install bedrock-agentcore-client. I ran:
pip install bedrock-agentcore-client
It installed successfully. No errors. That's because there's a placeholder package on PyPI with that name. It installs, imports fail silently, and your container builds successfully with a broken dependency inside.
The real SDK lives in AWS's CodeArtifact registry. You need to configure pip to pull from a private index:
aws codeartifact login --tool pip \
--domain amazon-agent-runtimes \
--repository agent-runtimes-pypi \
--domain-owner 600427722194
Then install from there. The PyPI package is a trap. Nobody warns you.
Hours lost: 3. The error only appears at runtime when the container tries to import the module. The build succeeds. The push succeeds. The deployment succeeds. The invocation returns an empty payload.
Failure 2: The 200 OK that means failure
After fixing the SDK, I deployed and invoked the agent:
aws bedrock-agentcore-control invoke-agent-runtime \
--agent-runtime-id abc123 \
--payload '{"job_description": "..."}'
Response: HTTP 200. Payload: empty string.
Not a 500. Not a 400. Not an error message. A successful HTTP response with nothing inside.
I checked CloudWatch. No logs. I checked the container status. Running. I checked the agent runtime status. Active.
The problem: my IAM role was missing bedrock:GetAgentRuntime permission. Without it, the invocation endpoint accepts the request, routes it nowhere, and returns a 200 with an empty body.
There is no error message. There is no log entry. The service returns success when it fails.
Hours lost: 5. I tried different payloads, different content types, different SDK versions, curl vs boto3, synchronous vs streaming. All 200 OK, all empty. The fix was one IAM permission that produces zero error signal when missing.
{
"Effect": "Allow",
"Action": "bedrock:GetAgentRuntime",
"Resource": "*"
}
Failure 3: The container that crashed with no logs
Next failure. Container starts, passes health checks for 30 seconds, then dies. No exception in CloudWatch. No crash log. Status shows "Failed" with no reason.
I added every logging statement I could think of. Print statements. Structured logging. Exception handlers wrapping every import. Nothing appeared in CloudWatch because the container never got far enough to initialize the logging framework.
The cause: missing USER 1000 directive in the Dockerfile.
# This crashes silently
FROM python:3.12-slim
WORKDIR /app
COPY . .
RUN pip install -e .
CMD ["python", "-m", "my_agent"]
# This works
FROM python:3.12-slim
RUN useradd -m -u 1000 agentuser
WORKDIR /app
COPY . .
RUN pip install -e .
USER 1000
CMD ["python", "-m", "my_agent"]
AgentCore requires the container to run as UID 1000. If it doesn't, the runtime kills the container. The error message in the console says "Failed." Just "Failed." No mention of user directives, permissions, or UID requirements.
I found this by reading the AgentCore team's GitHub sample repos. Not the docs. The sample Dockerfile.
Hours lost: 4.
Failure 4: The naming regex nobody documented
I wanted to name my agent runtime resume-tailor-agent. Deployment failed:
An error occurred (ValidationException):
Name must match pattern: ^[a-zA-Z0-9_]+$
No hyphens allowed. Fine. I renamed to resume_tailor_agent and moved on.
But the error message only appears if you use the control plane client. If you use the console, it just... doesn't submit. No red border, no error toast, no validation message. The button does nothing.
Hours lost: 1. Small one, but the pattern: silent failures.
The two-client split nobody mentions
Here's where it gets architectural. AgentCore has TWO Python clients:
-
bedrock-agentcore-controlfor managing runtimes (create, update, delete) -
bedrock-agentcorefor the runtime SDK (what runs inside your container)
The documentation uses both interchangeably. Code samples import from one in the setup section and the other in the invocation section. They have different install paths, different CodeArtifact repositories, and different API surfaces.
If you install the wrong one, nothing tells you. Your code runs until it hits an import that doesn't exist in the package you installed. And since both packages have overlapping module names in some versions, the error might be an AttributeError deep in a function call, not a clean ImportError at the top.
I mapped out which client does what:
| Client | Purpose | Install From |
|---|---|---|
bedrock-agentcore-control |
Create/manage runtimes | CodeArtifact (domain: amazon-agent-runtimes) |
bedrock-agentcore |
Runtime SDK (inside container) | CodeArtifact (same domain) |
boto3 (bedrock-agent) |
Invoke from outside | Standard pip |
This table doesn't exist in any documentation I found.
What I learned
Five days of debugging. Four distinct silent failures. Zero useful error messages.
Every single problem shared the same pattern: the system accepted the bad input, returned success, and failed somewhere downstream without signaling what went wrong. The 200 OK that means failure. The build that succeeds with a placeholder SDK. The container that crashes without logs.
If I'd had Sentry in the container from day one, I would have caught the import failure, the UID crash, and the empty response pattern within hours instead of days. Observability isn't optional for agent deployments. The infrastructure actively hides failures from you.
Three principles I'm carrying forward:
1. Never trust a 200 OK from a new service. Validate the response body. If it's empty, something broke silently upstream.
2. Test imports at container startup, before anything else. A try/except around every critical import with an explicit log line. If the SDK is fake, you'll know in the first second.
3. Read the sample repos, not just the docs. The Dockerfile in AWS's example repo had USER 1000. The documentation never mentioned it. The sample code is sometimes the real documentation.
I've since added Sentry to my agent pipeline for my security posture scanner project. The trace waterfalls catch problems in seconds that would have taken me hours with print statements. Lesson learned the hard way.
All errors described above are from July 2026 on AgentCore's GA release. Some may be fixed by the time you read this. The patterns of silent failure in new AWS services are probably eternal.
Top comments (17)
The missing logs before initialization issue is such a pain point. Aside from Sentry, did you find a clean way to direct standard error/stdout to CloudWatch during the container initialization phase before Python starts up?
Honestly no not really. The problem is AgentCore doesnt even create a log stream in cloudwatch until your app process actually writes something to stdout
after init. So if it dies before that you get literally nothing what I started doing after this whole mess is wrapping the entrypoint in a shell command that prints basic stuff before python starts
dockerfile
ENTRYPOINT ["/bin/sh", "-c", "echo container starting uid: $(id -u) && exec python -m my_agent"]
That way if it crashes on the uid thing you at least see the mismatch Its not pretty but would of saved me like 4 hours honestly
Brilliant idea. Simple, but it definitely solves that maddening 'black hole' logging behavior before the process spins up. Appreciate the tip!
Yes Thanks you!
Stay tune for the next article
dev.to/sarvar_04/sentrys-span-hier...
This is the gap between reported success and observed success. Builds, deployments and HTTP status codes are claims. BootProof exists to make software produce evidence: start the real system, exercise its declared readiness contract, validate the response, and sign what actually happened. No proof, no green check.
boot-proof.com
Thanks for sharing 🙏🏻
The throughline here is that the real failures were contract failures, not just bugs: package source ambiguity, success-shaped error responses, container runtime assumptions, and naming rules that only exist in rejection behavior. The 200 OK that still means failure is especially nasty because it trains teams to trust the wrapper status instead of the payload that actually explains the break.
We have seen the same thing in agent and platform workflows. If the receipt only preserves the outer status and not the rejected body, missing directive, or runtime contract that failed, the next engineer has to rediscover the whole trail from scratch.
Curious whether you ended up automating any preflight checks for those undocumented constraints before the next deploy.
Yeah contract failures is exactly what it was the system never broke http semantics technically it just gave you back a response that was completely useless with no signal about what went wrong.
For preflight I ended up writing a small deploy script that checks 3 things before pushing:
nothing fancy but catches the exact 3 failures i ran into the naming regex one i just hardcoded as a check on the string. Honestly wish AgentCore had some kind of dryrun flag that validated all this server side before you wait 5 minutes for a deploy that silently fails
The 200-OK-on-every-error part is the one that would have cost me a full day too. When the transport layer swallows the real status, I have started logging the raw response body before any SDK deserialization, because that is usually the only place the actual failure shows up. Did the AgentCore container give you anything at all in stdout, or did you end up reading the SDK source to reconstruct why it crashed?
Nothing zero stdout The container would start, pass health checks for about 30 seconds, then just die no log stream even got created in CloudWatch which told me it was crashing before the logging framework could initialize. I ended up reading the sample Dockerfiles in AWS's GitHub repos and that's where I spotted the USER 1000 directive mine was missing. For the empty 200 problem, yeah I wish I'd done what you're doing logging the raw response body before deserialization. The SDK was calling response.json() on an empty string and quietly returning None, so by the time my code saw it the failure was already gone. Would've saved me a solid 5 hours if I'd just printed response.text before that call.
Great write-up. Nothing wastes engineering time quite like a system that fails successfully. A
200 OKwith an empty response is not observability, it is gaslighting.:::
Thanks Edgar!
Stay tune for next detailed article....
This is Intresting
Thanks You!