langflow-ai/langflow · error · HTTPException
Project ID is required to start MCP server
Error message
Project ID is required to start MCP server
What it means
400 from get_project_sse: it was called with a falsy project_id (None or empty), so it cannot build the project-scoped SSE transport path /api/v1/mcp/project/{id}/. In practice the id should come from the request path; reaching this with None indicates the project context variable was never set — a server-side wiring bug or a route mounted without the project parameter resolved, not a client formatting mistake.
Source
Thrown at src/backend/base/langflow/api/v1/mcp_projects.py:281
).first()
if not project_access:
raise HTTPException(status_code=404, detail="Project not found")
return user
# Create project-specific context variable
current_project_ctx: ContextVar[UUID | None] = ContextVar("current_project_ctx", default=None)
# Mapping of project-specific SSE transports
project_sse_transports: dict[str, SseServerTransport] = {}
def get_project_sse(project_id: UUID | None) -> SseServerTransport:
"""Get or create an SSE transport for a specific project."""
if not project_id:
raise HTTPException(status_code=400, detail="Project ID is required to start MCP server")
project_id_str = str(project_id)
if project_id_str not in project_sse_transports:
project_sse_transports[project_id_str] = SseServerTransport(f"/api/v1/mcp/project/{project_id_str}/")
return project_sse_transports[project_id_str]
async def _build_project_tools_response(
project_id: UUID,
current_user: CurrentActiveMCPUser,
*,
mcp_enabled: bool,
) -> MCPProjectResponse:
"""Return tool metadata for a project."""
tools: list[MCPSettings] = []
try:
async with session_scope() as session:
# Fetch the project first to verify it exists and belongs to the current userView on GitHub (pinned to 976ec789d2)
Solutions
- Use the stock route path /api/v1/mcp/project/{project_id}/sse so FastAPI injects the id.
- If you forked/mounted routes, ensure the {project_id} path parameter name matches the endpoint signature.
- In tests, pass an explicit project UUID rather than relying on the context var.
- Check that auth dependencies that set current_project_ctx run before the SSE handler.
Defensive patterns
Strategy: validation
Validate before calling
def has_project_id(pid) -> bool:
return pid is not None and str(pid) != '' Try / catch
except 400 'Project ID is required': this is a routing/wiring defect — verify the endpoint path includes the project UUID; no client retry helps.
Prevention
- Use the stock /api/v1/mcp/project/{project_id}/sse route shape.
- In tests, pass explicit UUIDs instead of relying on context variables.
When it happens
Trigger: An SSE connect request where the project_id dependency resolved to None (route mismatch, misconfigured path parameter, or code calling get_project_sse(current_project_ctx.get()) before the context var was set).
Common situations: Custom deployments or forks that mount the MCP project routes under a different path pattern; race where the SSE connect handler runs before _bind_project_context; tests invoking handlers directly without the path param.
Related errors
- Failed to load file (HTTP ${status})
- Failed to install MCP
- No supported files found in folder. Allowed types: ${types?.
- File type ${fileExtension} not allowed. Allowed types: ${typ
- MCP Server disconnected, error: {e}
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/5da88cfcd9b30763.
Report an issue: GitHub.