BerriAI/litellm · error · HTTPException
Only admins or team admins can create projects. Your role is
Error message
Only admins or team admins can create projects. Your role is {user_api_key_dict.user_role} What it means
POST /project/new authorizes via _check_user_permission_for_project: only proxy admins or admins of the specific target team may create projects for it. If the caller's role/team membership does not satisfy this, the proxy returns HTTP 403 including the caller's actual role. This prevents a team admin from creating projects under another team's namespace.
Source
Thrown at enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py:387
team_object = await _validate_team_exists(team_id=data.team_id, prisma_client=prisma_client)
# Validate project limits against team limits
_check_team_project_limits(
team_object=LiteLLM_TeamTable.model_validate(team_object.model_dump()),
data=data,
)
# Check if user has permission to create projects for this team
# only team admins can create projects for their team
has_permission = await _check_user_permission_for_project(
user_api_key_dict=user_api_key_dict,
team_id=data.team_id,
prisma_client=prisma_client,
team_object=LiteLLM_TeamTable.model_validate(team_object.model_dump()),
)
if not has_permission:
raise HTTPException(
status_code=403,
detail={
"error": f"Only admins or team admins can create projects. Your role is {user_api_key_dict.user_role}"
},
)
# Generate project_id if not provided
if data.project_id is None:
data.project_id = str(uuid.uuid4())
else:
# Check if project_id already exists
existing_project = await prisma_client.db.litellm_projecttable.find_unique(
where={"project_id": data.project_id}
)
if existing_project is not None:
raise ProxyException(
message=f"Project id = {data.project_id} already exists. Please use a different project id.",
type="bad_request",View on GitHub (pinned to 6c2dcb801b)
Solutions
- Have a proxy admin or the target team's admin perform the creation (or use an admin key)
- Add the user as an admin of the team (PUT /team/update with the user in team_admin list / admin role) and retry
- If the caller should be a proxy admin, issue the key from an admin user or use the master key
Example fix
# before (member-level key)
curl -H 'Authorization: Bearer sk-member-key' -X POST .../project/new -d '{"team_id":"t1",...}'
# after (admin key)
curl -H 'Authorization: Bearer sk-admin-key' -X POST .../project/new -d '{"team_id":"t1",...}' Defensive patterns
Strategy: validation
Validate before calling
# Verify caller's role/team-admin status before attempting creation
me = await client.get('/user/info')
if not me.user_info.get('user_role') in ('proxy_admin', 'proxy_admin_viewer'):
team = await client.get(f'/team/info?team_id={team_id}')
admins = [m['user_id'] for m in (team.teams[0].members_with_roles or []) if m.get('role') == 'admin']
if me.user_id not in admins:
raise PermissionError('Caller cannot create projects for this team') Type guard
const canCreateProject = (userRole, userId, team) =>
userRole === 'proxy_admin' ||
(team.members_with_roles ?? []).some(
(m) => m.user_id === userId && m.role === 'admin'
); Try / catch
catch (e) {
if (e.status === 403 && /Only admins or team admins can create projects/.test(e.body?.detail?.error ?? '')) {
throw new Error(`Permission denied (role=${myRole}); ask a proxy/team admin to create the project`);
}
throw e;
} Prevention
- Run provisioning automation with a dedicated proxy-admin service key
- Keep team admin lists in sync with the people running project automation
When it happens
Trigger: Calling POST /project/new with a virtual key whose user is a member (not admin) of data.team_id, or an internal-user key with no team affiliation, e.g. role 'internal_user' targeting a team they do not administer.
Common situations: A team member with an own-api-key trying to self-provision a project, service accounts without admin grants, or an org_admin key targeting a team outside their scope.
Related errors
- Only admins or team admins can update projects
- Cannot reassign project to a team you are not an admin of
- An error occurred: {str(e)}, banned_keywords_list={banned_ke
- Model '{m}' not in team's allowed models. Team allowed model
- Project max_budget ({data.max_budget}) exceeds team's max_bu
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/feb68cbd01a558e4.
Report an issue: GitHub.