langgenius/dify · error · AgentNotFoundError
Agent not found.
Error message
Agent not found.
What it means
Raised as AgentNotFoundError when serializing an Agent App detail: neither the direct Agent lookup (by agent_id) nor roster_service.get_app_backing_agent returned an Agent. The App exists (it passed setup/login) but has no ACTIVE Agent backing it, so the roster-shaped detail cannot be built. This is an inconsistency between the App row and the Agent roster.
Source
Thrown at api/controllers/console/agent/roster.py:388
roster_service = _agent_roster_service(session)
payload = AgentAppDetailWithSite.model_validate(
app_model,
from_attributes=True,
context={"session": session},
).model_dump(mode="json")
agent = (
session.scalar(
select(Agent).where(
Agent.tenant_id == app_model.tenant_id,
Agent.id == agent_id,
Agent.status == AgentStatus.ACTIVE,
)
)
if agent_id
else roster_service.get_app_backing_agent(tenant_id=app_model.tenant_id, app_id=str(app_model.id))
)
if not agent:
raise AgentNotFoundError()
payload.pop("bound_agent_id", None)
payload["app_id"] = agent.app_id
payload["backing_app_id"] = roster_service.runtime_backing_app_id(agent)
payload["hidden_app_backed"] = bool(agent.backing_app_id and agent.backing_app_id != agent.app_id)
payload["id"] = agent.id
debug_conversation_id = roster_service.get_or_create_build_conversation(
tenant_id=app_model.tenant_id,
agent_id=agent.id,
account_id=current_user.id,
commit=False,
)
message_count = roster_service.count_agent_app_debug_conversation_messages(
conversation_id=debug_conversation_id,
)
payload["debug_conversation_id"] = debug_conversation_id
payload["debug_conversation_has_messages"] = message_count > 0
payload["debug_conversation_message_count"] = message_count
payload["role"] = agent.role or ""View on GitHub (pinned to ef8544b173)
Solutions
- Confirm an ACTIVE Agent exists for the App: SELECT * FROM agents WHERE app_id=<app_id> AND status='active'; re-create/re-publish if missing.
- If the Agent was intentionally deactivated, archive the App or rebind it to an active Agent.
- Check bound_agent_id on the App row matches an existing Agent in the same tenant.
- In fixtures, ensure the backing Agent row is created and ACTIVE before hitting the detail endpoint.
Defensive patterns
Strategy: validation
Validate before calling
from sqlalchemy import select
from models.agent import Agent, AgentStatus
def app_has_active_agent(session, app_model) -> bool:
return session.scalar(
select(Agent.id).where(
Agent.tenant_id == app_model.tenant_id,
Agent.app_id == app_model.id,
Agent.status == AgentStatus.ACTIVE,
).limit(1)
) is not None Try / catch
from services.errors.agent import AgentNotFoundError
try:
detail = fetch_agent_app_detail(app_id)
except AgentNotFoundError:
# backing Agent missing/non-ACTIVE: rebind or restore before retry
raise Prevention
- Keep the backing Agent ACTIVE for any App exposed in the roster.
- When deactivating an Agent, also archive or rebind the App.
- In fixtures, create the ACTIVE backing Agent before hitting the detail endpoint.
When it happens
Trigger: GET /console/agents/<agent_id>/apps/<app_id> (or the app detail serializer) for an App whose bound_agent_id points to a non-ACTIVE or missing Agent, or whose backing-agent lookup returns None. Distinguishable from 200/201 because it fires in the detail serializer, not the publish-visibility path.
Common situations: App whose Agent was soft-deleted or set to a non-ACTIVE status; app created by an older flow that did not provision the backing Agent; cross-tenant reference; race during Agent deactivation while the detail page is open.
Related errors
- export response missing data field
- reconnect stream body missing
- unknown
- usage_missing_arg
- usage_missing_arg
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/2837b1d100445cf1.
Report an issue: GitHub.