{"record":{"id":"5393e1d6e63e4a64","repo":"infiniflow/ragflow","slug":"agent-not-found","errorCode":null,"errorMessage":"Agent not found.","messagePattern":"Agent not found\\.","errorType":"exception","errorClass":"LookupError","httpStatus":null,"severity":"error","filePath":"api/db/services/canvas_service.py","lineNumber":341,"sourceCode":"\n        e, c = UserCanvasService.get_by_canvas_id(canvas_id)\n        if not e:\n            return False\n\n        tids = [t.tenant_id for t in UserTenantService.query(user_id=tenant_id)]\n        if c[\"user_id\"] == tenant_id:\n            return True\n        if c[\"user_id\"] not in tids:\n            return False\n        if c[\"permission\"] != TenantPermission.TEAM.value:\n            return False\n        return True\n\n    @classmethod\n    def get_agent_dsl_with_release(cls, agent_id, release_mode=False, tenant_id=None):\n        e, cvs = cls.get_by_id(agent_id)\n        if not e:\n            raise LookupError(\"Agent not found.\")\n\n        if release_mode:\n            released_version = UserCanvasVersionService.get_latest_released(agent_id)\n            if not released_version:\n                raise PermissionError(\"No available published version\")\n            dsl = released_version.dsl\n        else:\n            dsl = cvs.dsl\n\n        if not isinstance(dsl, str):\n            dsl = json.dumps(dsl, ensure_ascii=False)\n\n        return cvs, dsl\n\n\nasync def completion(tenant_id, agent_id, session_id=None, **kwargs):\n    query = kwargs.get(\"query\", \"\") or kwargs.get(\"question\", \"\")\n    files = kwargs.get(\"files\", [])","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/api/db/services/canvas_service.py#L323-L359","documentation":"LookupError raised by UserCanvasService.get_agent_dsl_with_release when cls.get_by_id(agent_id) returns nothing: no user_canvas row exists for that agent id. The function loads an agent's DSL (optionally its latest released version), so a missing canvas row means the agent was deleted or the id is wrong. Callers include the completion() flow when no session_id is given.","triggerScenarios":"POSTing a completion/run request with an agent_id that doesn't exist; agent deleted between page load and run; id truncated or from another environment; releasing/running an id that was a session id by mistake.","commonSituations":"Stale agent picker in the UI after another user deleted the agent; API scripts with hard-coded agent ids; importing conversations without importing the canvases.","solutions":["Verify the agent exists for the tenant (user_canvas table / GET /api/v1/canvases) and copy the correct id.","If deleted, restore or recreate the agent and update the caller's stored id.","Handle the LookupError in clients with a 404-style response instead of retrying.","Check you are passing agent_id, not session_id, to endpoints that expect an agent."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"exist, cvs = UserCanvasService.get_by_id(agent_id)\nif not exist:\n    raise ValueError(f\"Agent {agent_id} not found; check the id in GET /api/v1/canvases\")","typeGuard":"def agent_exists(agent_id: str) -> bool:\n    return UserCanvasService.get_by_id(agent_id)[0]","tryCatchPattern":"try:\n    cvs, dsl = UserCanvasService.get_agent_dsl_with_release(agent_id, ...)\nexcept LookupError:\n    return jsonify(error=\"Agent not found\"), 404","preventionTips":["Return 404 (not 500) when this LookupError reaches an HTTP handler.","Refresh agent ids in clients after deletion events.","Distinguish agent_id from session_id in run/completion payloads."],"tags":["agent","canvas","lookup","ragflow"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}