{"record":{"id":"021c62f067c98ce2","repo":"langflow-ai/langflow","slug":"no-ingestion-job-found-for-the-knowledge-base-kb","errorCode":null,"errorMessage":"No ingestion job found for the knowledge base {kb_name}","messagePattern":"No ingestion job found for the knowledge base (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"warning","filePath":"src/backend/base/langflow/api/v1/knowledge_bases.py","lineNumber":2292,"sourceCode":"    _assert_kb_not_memory_base(kb_name, _kb_guard.owner_user)\n    try:\n        kb_path = _resolve_kb_path(kb_name, _kb_guard.owner_user)\n\n        # ``asset_id`` is now sourced from ``KnowledgeBaseRecord.id``\n        # (the indexed column on ``job.asset_id``); legacy KBs that\n        # only exist on disk fall back to ``metadata['id']``.\n        metadata = KBAnalysisHelper.get_metadata(kb_path, fast=True)\n        asset_id = await _resolve_kb_asset_id(\n            kb_name=kb_name,\n            current_user=current_user,\n            metadata=metadata,\n        )\n\n        # Fetch the latest ingestion job for this KB\n        latest_jobs = await job_service.get_latest_jobs_by_asset_ids([asset_id])\n\n        if asset_id not in latest_jobs:\n            raise HTTPException(status_code=404, detail=f\"No ingestion job found for the knowledge base {kb_name}\")\n\n        job = latest_jobs[asset_id]\n        job_status = job.status.value if hasattr(job.status, \"value\") else str(job.status)\n\n        # Check if job is already completed or failed\n        if job_status in [\"completed\", \"failed\", \"cancelled\", \"timed_out\"]:\n            raise HTTPException(status_code=400, detail=f\"Cannot cancel job with status '{job_status}'\")\n\n        revoked = await task_service.revoke_task(job.job_id)\n        # Update status immediately so background task can see it\n        await job_service.update_job_status(job.job_id, JobStatus.CANCELLED)\n\n        # Clean up any partially ingested chunks from this job. Forward\n        # the KB's configured backend + user_id so non-Chroma KBs\n        # (Mongo/Astra/Postgres) actually find their variable-backed\n        # credentials and delete against the right store — otherwise\n        # cleanup silently falls back to Chroma and remote chunks\n        # written before the cancel stick around.","sourceCodeStart":2274,"sourceCodeEnd":2310,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/src/backend/base/langflow/api/v1/knowledge_bases.py#L2274-L2310","documentation":"404 from POST /api/v1/knowledge_bases/{kb_name}/cancel. The endpoint resolves the KB's asset id (from metadata, falling back to a DB lookup) and asks job_service.get_latest_jobs_by_asset_ids for the newest ingestion job. If no job exists for that asset id — never ingested, or the asset id resolved differently (e.g. KB created on disk before metadata carried an id) — you get this 404.","triggerScenarios":"Cancelling a KB that has never had an ingestion job; cancelling right after the job record expired or was cleared; KB restored/moved so metadata['id'] no longer matches the job's asset id.","commonSituations":"UI shows a spinning ingestion for a KB whose job was created before a server restart wiped the job store (non-persistent job backend); user clicks Cancel on a fresh KB with no ingestion yet; asset-id mismatch after KB rename/copy.","solutions":["Confirm an ingestion is actually running: check GET /{kb_name}/runs or the job list for that KB","If the job store is in-memory, restarts clear it — the ingestion is not cancellable; let it finish or restart the server","Verify the KB metadata id matches what the job was created with (KBAnalysisHelper.get_metadata)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"runs = await client.get(f\"/api/v1/knowledge_bases/{kb_name}/runs\")\nhas_activity = len(runs.json()[\"results\"]) > 0\nif not has_activity:\n    skip_cancel()  # nothing to cancel; avoid the 404","typeGuard":null,"tryCatchPattern":"try:\n    await client.post(f\"/api/v1/knowledge_bases/{kb_name}/cancel\")\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 404:\n        return  # no live job — treat as already idle\n    raise","preventionTips":["Only show a Cancel control when the runs/jobs list shows a live job","Remember job stores can be in-memory: after a restart, old jobs are uncancellable","Treat cancel-404 as a no-op, not an error"],"tags":["knowledge-base","ingestion","cancel","http-404","langflow"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}