opendatalab/MinerU · error · HTTPException

Task manager is not initialized

Error message

Task manager is not initialized

What it means

HTTP 503 raised by get_task_manager() in fast_api.py when app.state.task_manager is None (or missing). The AsyncTaskManager is created during the FastAPI lifespan/startup hook; if a request is served before lifespan ran, or lifespan failed partway, every task endpoint returns 503 with this detail. It is a server-initialization problem, never a client-input problem.

Source

Thrown at mineru/cli/fast_api.py:1224

    def _is_task_expired(self, task: AsyncParseTask, now: datetime) -> bool:
        if task.status not in (TASK_COMPLETED, TASK_FAILED):
            return False
        if not task.completed_at:
            return False
        try:
            completed_at = datetime.fromisoformat(task.completed_at)
        except ValueError:
            logger.warning(f"Invalid completed_at for task {task.task_id}: {task.completed_at}")
            return False
        if completed_at.tzinfo is None:
            completed_at = completed_at.replace(tzinfo=timezone.utc)
        return (now - completed_at).total_seconds() >= self.task_retention_seconds


def get_task_manager() -> AsyncTaskManager:
    task_manager = getattr(app.state, "task_manager", None)
    if task_manager is None:
        raise HTTPException(status_code=503, detail="Task manager is not initialized")
    return task_manager


@app.post(
    path="/file_parse",
    status_code=200,
    summary="Synchronously parse uploaded files",
    description=(
        "Submit a parsing task to the shared async task manager, wait for it to "
        "finish, and return the final parsing result in the same response."
    ),
)
async def parse_pdf(
    http_request: Request,
    background_tasks: BackgroundTasks,
    request_options: Annotated[
        ParseRequestOptions, Depends(parse_request_form)
    ],

View on GitHub (pinned to 4fe4bde114)

Solutions

  1. Ensure requests only flow after startup: with TestClient(app) as client: ... (the with-block triggers lifespan).
  2. Check the server startup logs for the underlying lifespan exception (model download, CUDA init, port issues) and fix that first.
  3. If embedding the app, run its lifespan or set app.state.task_manager explicitly before serving traffic.
  4. Retry with backoff on 503 from orchestrators that start before the app is warm.

Example fix

# before (test never initializes the manager)
client = TestClient(app)
r = client.get('/tasks/abc')  # 503 Task manager is not initialized

# after
with TestClient(app) as client:  # enters lifespan, manager created
    r = client.get('/tasks/abc')  # 404 Task not found — manager alive
Defensive patterns

Strategy: validation

Validate before calling

# before any request in tests/embeddings, verify lifespan ran
from fastapi.testclient import TestClient
with TestClient(app) as client:  # enters lifespan -> task_manager created
    client.get('/tasks/abc')

Type guard

def task_manager_ready(app) -> bool:
    return getattr(app.state, 'task_manager', None) is not None

Try / catch

r = client.get(f'{base}/tasks/{task_id}')
if r.status_code == 503:
    raise RuntimeError('API not warmed up / lifespan failed — check startup logs')

Prevention

When it happens

Trigger: Using fastapi.testclient.TestClient or httpx ASGI transport without entering the lifespan context (no 'with TestClient(app) as c:'); mounting the mineru app inside another app without running its lifespan; lifespan startup crashed (e.g. model load failure) but the process still serves; importing the app module and running it with a server that skips lifespan.

Common situations: Writing tests against the API without lifespan; embedding the app in a larger service; startup errors being swallowed so the app runs half-initialized; exotic ASGI servers with lifespan disabled.

Related errors


AI-assisted analysis of opendatalab/MinerU@4fe4bde114 (2026-08-14). Data as JSON: /api/errors/3da8e1138a67ad92. Report an issue: GitHub.