langflow-ai/langflow · warning · HTTPException

resource_ids capped at {_MAX_RESOURCE_IDS}

Error message

resource_ids capped at {_MAX_RESOURCE_IDS}

What it means

Route-level guard on the /authz/me effective-permissions endpoint: the resource_ids list in the request body is capped at _MAX_RESOURCE_IDS entries. Exceeding it raises HTTP 400 with detail 'resource_ids capped at {_MAX_RESOURCE_IDS}'.

Source

Thrown at src/backend/base/langflow/api/v1/authz_me.py:184

    return normalized


@router.post("/permissions", response_model=EffectivePermissionsResponse)
async def get_effective_permissions(
    body: EffectivePermissionsRequest,
    current_user: CurrentActiveUser,
    session: DbSessionReadOnly,
) -> EffectivePermissionsResponse:
    """Return per-resource allowed actions for the current user.

    Use this to render the UI permission gate (greyed-out buttons etc.) without
    flooding the audit log with denied probes. Empty list for a resource_id
    means the user cannot perform any of the requested actions on that resource.
    """
    if not body.resource_ids:
        return EffectivePermissionsResponse(resource_type=body.resource_type, permissions={})
    if len(body.resource_ids) > _MAX_RESOURCE_IDS:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"resource_ids capped at {_MAX_RESOURCE_IDS}",
        )

    authz = get_authorization_service()
    actions = tuple(body.actions) if body.actions else _DEFAULT_ACTIONS
    permissions = await authz.get_effective_permissions(
        user_id=current_user.id,
        resource_type=body.resource_type,
        resource_ids=body.resource_ids,
        actions=actions,
        domain=body.domain,
        context={
            **current_auth_context_for_authz(),
            "is_superuser": current_user.is_superuser,
        },
    )
    permissions = await _apply_owner_permissions(

View on GitHub (pinned to 976ec789d2)

Solutions

  1. Chunk resource_ids into batches of at most _MAX_RESOURCE_IDS and merge the responses
  2. Filter the list first to only resources actually being rendered
  3. If the UI shows paginated results, request permissions only for the current page's ids
  4. Persist batch size in one client constant so it can be tuned alongside the server cap

Example fix

// before
const res = await api.post('/authz/me/effective-permissions', { resource_type, resource_ids: allIds });

// after
const chunks = [];
for (let i = 0; i < allIds.length; i += 100) chunks.push(allIds.slice(i, i + 100));
const results = await Promise.all(chunks.map(c => api.post('/authz/me/effective-permissions', { resource_type, resource_ids: c })));
const permissions = Object.assign({}, ...results.map(r => r.permissions));
Defensive patterns

Strategy: validation

Validate before calling

const MAX_RESOURCE_IDS = 100; // keep in sync with _MAX_RESOURCE_IDS
function chunk<T>(arr: T[], n: number): T[][] {
  const out: T[][] = [];
  for (let i = 0; i < arr.length; i += n) out.push(arr.slice(i, i + n));
  return out;
}

Prevention

When it happens

Trigger: POST /authz/me/effective-permissions with a resource_ids array longer than _MAX_RESOURCE_IDS — e.g. a dashboard that loads every flow in a workspace and asks permissions for all of them in one call.

Common situations: Workspaces that grew past the cap over time, 'select all' UI actions, or clients that page through resource lists and then batch the entire accumulated set into one permissions call.

Related errors


AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14). Data as JSON: /api/errors/5a3e5bc7a5b27532. Report an issue: GitHub.