Troubleshooting
Find your error message below (headings use the real strings, so search works), then apply the fix. Every API error arrives in the envelope {"error": "<message>", "request_id": "<id>"} — include the request_id when you contact support.
Deploying
"this project is at its service limit"
Full message (409 on deploy):
this project is at its service limit (10 / 10): deploying needs at least one more service and cannot proceed. Delete an agent or function, or ask an admin to raise the project's service quota, then deploy.
Cause: every agent and function counts against the project's service quota, and the project is full.
Fix: exactly what the message says — platformctl delete <agent> something you no longer need, or ask a project admin to raise the quota (see quotas and audit), then deploy again.
A related variant appears when the quota fills up mid-deploy: the agent sticks at deploying and its message field reads This project is at its service limit (10 / 10), so the new revision cannot get a network route yet - .... Same cause, same fix; the deploy completes once room exists.
"missing or invalid 'name' (must be a lowercase DNS label)"
Cause: agent names must match ^[a-z]([a-z0-9-]{0,61}[a-z0-9])?$ — lowercase letters, digits, and hyphens, starting with a letter, at most 63 characters. MyAgent, my_agent, and my agent are all invalid. On name-addressed routes the same rule produces 400 invalid agent name (must be a lowercase DNS label).
Fix: rename to something like my-agent. Names are immutable after deploy — pick one you can live with.
"a build is already in progress for agent"
Full message: 409 a build is already in progress for agent research-buddy.
Cause: two deploys of the same agent raced; only one build may run at a time.
Fix: wait for the in-flight build to finish (platformctl status <agent>), then redeploy. If a build crashed and left a stale claim, it becomes reclaimable after 30 minutes — retry then.
Status is failed after a deploy
Cause: the build itself failed — usually a bad requirements.txt pin or a broken Dockerfile step.
Fix: read the build output. There is no separate build-log endpoint; the tail of the build output (up to 4,000 characters) lands in the agent's message field:
platformctl status my-agent
Look for the failing pip install or compile error near the end. Note for LangGraph and CrewAI agents: dependency pins that conflict with the platform's base image fail here, at build time, on purpose — better than crashing at import time in production.
"could not import root_agent from /app/agent/agent.py"
Full message (in the agent's status message, after the pod crash-loops):
could not import `root_agent` from /app/agent/agent.py - the agent image must define a module-level `root_agent` in agent.py
Cause: the build succeeded, but your code doesn't meet the framework's entry-point contract, so the harness can't load it.
Fix: export the required module-level symbol for your framework:
| Framework | File | Must export |
|---|---|---|
| ADK | agent.py | root_agent |
| LangGraph | graph.py | graph (a compiled StateGraph) |
| CrewAI | crew.py | crew (a crewai.Crew or a zero-argument factory) |
See ADK, LangGraph, and CrewAI.
"'runtime' only applies to framework=function"
Cause: you sent a runtime form field (e.g. nodejs) while deploying an agent. Agents are Python; only functions choose a runtime.
Fix: drop the runtime field, or deploy a function if that's what you meant.
"no source is stored for this agent - deploy it once from the CLI or upload files first"
Cause: you called POST /v1/agents/{name}/redeploy (or the console editor's deploy button), but the platform has no stored source for this agent — source storage is best-effort.
Fix: deploy once with platformctl deploy <dir> (which stores the source), or create files via the files API, then redeploy.
Ownership and visibility (the 404 rule)
"unknown agent" — but you're sure it exists
Full message: 404 unknown agent: research-buddy.
Cause: on this platform, "doesn't exist" and "exists but isn't yours" are deliberately the same 404 — the API never confirms the existence of a resource you can't access. If someone else owns an agent with that name, you get this 404 too, including when you try to deploy over it.
Fix: check you're signed in as the right user (platformctl whoami) and pointed at the right project (--project or platformctl config set-project). If a teammate owns the agent, ask them or a project admin.
"this agent has no recorded owner, so only a project admin can manage it"
Full message (403): this agent has no recorded owner, so only a project admin can manage it (a project admin can adopt it by redeploying it). The deploy-time variant: an agent named research-buddy already exists and has no recorded owner, so only a project admin can redeploy it.
Cause: the agent was deployed without a user identity (for example, with the automation token), so there is no owner to match you against.
Fix: have a project admin redeploy it — that adopts it and records an owner.
"the agent name ... exists in more than one project"
Full message (409): the agent name research-buddy exists in more than one project; add ?project=<slug> to say which one, or sign in so it resolves within your project.
Cause: agents are addressed by name, and two projects you can see both have one with this name.
Fix: add ?project=<slug> to the request (or --project on the CLI), or sign in so resolution happens inside your own project.
Invoking
"message is required"
Cause: the invoke body was missing a message, or it was blank.
Fix: send {"message": "..."}. See invoke for the full shape.
"session_id chosen by an unauthenticated caller must be at least 24 characters"
Full message (400):
session_id chosen by an unauthenticated caller must be at least 24 characters of unguessable randomness (or omit it and the platform will generate one). A short, guessable id would let anyone else read this conversation.
Cause: you invoked anonymously with a short, guessable session_id like s1. Anyone who guessed it could continue — and read — your conversation.
Fix: omit session_id and save the one the platform returns, or generate 24+ random characters, or authenticate.
"memorize requires authentication"
Full message (401): memorize requires authentication: it writes durable memory that later callers read back. Invoke without 'memorize', then call POST /v1/agents/{name}/sessions/{id}/memorize with a session token.
Cause: memorize writes to the shared memory bank, which every future caller reads — so it always requires a signed-in caller, even though invoke itself doesn't.
Fix: platformctl login, then use platformctl memorize <agent> --session <id> or send a bearer token.
The agent answers, but turn 2 forgot turn 1
Cause: the session_id changed between calls, or you supplied two different user_id values yourself.
Fix: reuse the same session_id on every turn (--session on the CLI). If you set user_id manually, keep it constant too — or omit it and the platform derives a stable one. See sessions.
First invoke after idle is slow, or times out
Cause: cold start. Idle agents scale to zero; the first request must schedule a pod, start the harness, and import your code — all inside the invoke timeout (60 seconds by default). Heavy imports can push the first call over the line; the retry then hits a warm pod and succeeds.
Fix: retry once — a warm instance answers fast. To eliminate cold starts on a latency-sensitive agent, set min_scale: 1 in its compute config (the Configure modal in the console, or PATCH /v1/agents/{name}/config) to keep one instance always on. See traffic and revisions.
The agent replies with model authentication errors
Cause: no model credential is in force — the platform default is missing and the agent has no MODEL_API_KEY secret of its own.
Fix: check without exposing anything — the agent's own URL serves an unauthenticated GET /debug/config that reports model_key_present: true/false and the resolved model. If it's false, set a key: platformctl secrets set <agent> MODEL_API_KEY=sk-... (see secrets and env).
"this is a management endpoint and requires authentication"
Full message (401): this is a management endpoint and requires authentication. Sign in (POST /v1/auth/login) and send 'Authorization: Bearer <token>', or use the automation token: kubectl -n cai-agents get secret cai-automation-token -o jsonpath='{.data.token}' | base64 -d
Cause: deploy, logs, secrets, files, revisions, and session browsing all require a credential; only invoke is open by default.
Fix: platformctl login, or send Authorization: Bearer $CAI_TOKEN. For CI, use a service-account API key — see service accounts and API keys.
Sessions, memory, and logs
"session browsing is not configured"
Full message (503): session browsing is not configured: the control plane has no CAI_INTERNAL_TOKEN, so it cannot authenticate to the agent's read surface.
Cause: the control plane lacks the internal credential it uses to read transcripts from agents. This is platform configuration, not something you did.
Fix: ask your administrator to configure CAI_INTERNAL_TOKEN on the platform.
"the user_id query parameter is required"
Cause: GET /v1/agents/{name}/sessions lists sessions per user; it needs ?user_id=.
Fix: list users first (GET /v1/agents/{name}/users), then pass one id. See sessions.
"agent ... has no live pods: it is scaled to zero"
Full message (200, not an error):
agent research-buddy has no live pods: it is scaled to zero (no running replicas), which is normal for an idle serverless agent - it cold-starts on the next invoke. For logs from earlier runs, use GET /v1/agents/research-buddy/logs/history.
Cause: the agent is idle. Live logs need a live pod.
Fix: nothing is wrong. Use platformctl logs <agent> --history for earlier runs — history survives scale-to-zero and is retained 14 days by default. See logs.
"--follow and --history are mutually exclusive"
Full message: --follow and --history are mutually exclusive: --history reads persisted logs, --follow tails the live pod.
Fix: pick one: -f to tail the live pod, --history for persisted lines.
Traffic and revisions
"traffic is required - send the complete split"
Full message (400): traffic is required - send the complete split, e.g. [{"revision_name":"research-buddy-00002","percent":100}].
Cause: set-traffic replaces the entire routing table; an empty or partial body is ambiguous.
Fix: send every revision that should serve, with percentages summing to 100. See traffic and revisions.
"revision ... does not exist for this agent"
Cause: a typo in revision_name, or the revision belongs to a different agent.
Fix: list valid names with GET /v1/agents/{name}/revisions and copy one exactly (e.g. research-buddy-00002).
Still stuck?
- Every error carries a
request_id— quote it when you ask for help. - The platform is in alpha; some rough edges are documented rather than fixed. Check known issues and the platform-wide troubleshooting page.