bytedance/deer-flow · error · HTTPException

Agent '{name}' only exists in the legacy shared layout and i

Error message

Agent '{name}' only exists in the legacy shared layout and is not scoped to a user. Run scripts/migrate_user_isolation.py to move legacy agents into the per-user layout before deleting.

What it means

409 on DELETE `/agents/{name}`: the store returned outcome 'legacy' — the agent exists only in the legacy shared layout, not scoped to the deleting user. Deletion is blocked because removing a shared-layout agent would affect all users; the operator must migrate first. Same legacy-layout concept as the PUT-side 409, resolved by the same script.

Source

Thrown at backend/app/gateway/routers/agents.py:562

    Raises:
        HTTPException: 404 if no per-user copy exists; 409 if only a legacy
            shared copy exists (suggesting the migration script).
    """
    _require_agents_api_enabled()
    _validate_agent_name(name)
    name = _normalize_agent_name(name)
    user_id = get_effective_user_id()
    store = get_agent_store()

    try:
        # Off the event loop: file rmtree or a DB delete plus memory cleanup.
        outcome = await asyncio.to_thread(store.delete, name, user_id=user_id)
    except Exception as e:
        logger.error(f"Failed to delete agent '{name}': {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Failed to delete agent: {str(e)}")

    if outcome == "legacy":
        raise HTTPException(
            status_code=409,
            detail=(f"Agent '{name}' only exists in the legacy shared layout and is not scoped to a user. Run scripts/migrate_user_isolation.py to move legacy agents into the per-user layout before deleting."),
        )
    if outcome == "missing":
        raise HTTPException(status_code=404, detail=f"Agent '{name}' not found")
    if outcome == "not-custom-agent":
        raise HTTPException(
            status_code=409,
            detail=(f"Directory for '{name}' contains memory data but is not a custom agent because config.yaml is missing; it was preserved."),
        )

    logger.info(f"Deleted agent '{name}'")

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Run `scripts/migrate_user_isolation.py` to move legacy agents into per-user scope, then delete the migrated copy
  2. Alternatively remove the legacy shared agent manually with operator intent (it is shared — deleting it affects everyone)
  3. Re-run the delete and expect 204 on success

Example fix

# before
DELETE /agents/legacy-agent  # 409
# after
python scripts/migrate_user_isolation.py
DELETE /agents/legacy-agent  # 204
Defensive patterns

Strategy: try-catch

Try / catch

try { await api.deleteAgent(name); }
catch (e) {
  if (e.status === 409 && /legacy shared layout/.test(e.detail)) {
    showAdminNotice('Run scripts/migrate_user_isolation.py first; this agent is shared');
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Deleting a pre-isolation shared agent on an upgraded file-backend deployment; admin cleanup scripts walking old agent names.

Common situations: Post-upgrade housekeeping hitting 409 on every legacy agent; mixed layouts after partial migration.

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/5bfa3c54dac9b792. Report an issue: GitHub.