{"record":{"id":"d778e055d39372ee","repo":"infiniflow/ragflow","slug":"no-available-published-version","errorCode":null,"errorMessage":"No available published version","messagePattern":"No available published version","errorType":"exception","errorClass":"PermissionError","httpStatus":null,"severity":"error","filePath":"api/db/services/canvas_service.py","lineNumber":346,"sourceCode":"        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\", [])\n    inputs = kwargs.get(\"inputs\", {})\n    user_id = kwargs.get(\"user_id\", \"\")\n    chat_template_kwargs = kwargs.get(\"chat_template_kwargs\")\n    custom_header = kwargs.get(\"custom_header\", \"\")\n    release_mode = str(kwargs.get(\"release\", \"\")).strip().lower()","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/api/db/services/canvas_service.py#L328-L364","documentation":"PermissionError raised by get_agent_dsl_with_release when release_mode is true but UserCanvasVersionService.get_latest_released(agent_id) returns nothing: the agent exists yet has no published (released) version. Release mode serves the last published DSL snapshot, so an agent that was never published — or whose release records were removed — cannot be served in release mode. The distinct exception type (PermissionError vs LookupError) lets callers distinguish 'not published' from 'not found'.","triggerScenarios":"Calling agent completion/run with release='true' before publishing the agent; publishing was rolled back or version rows cleared; release flag passed as any string that lowercases to 'true' (e.g. 'True') on an unpublished draft.","commonSituations":"Embedding a published-agent endpoint and hitting it before the first publish; republishing workflow where the old release was deleted; draft agents shared by id with release mode assumed.","solutions":["Publish (release) the agent first, then call with release mode.","Or drop the release flag to run the current draft DSL.","In clients, catch PermissionError separately and prompt 'agent not published yet'.","After deleting releases, republish before re-enabling release-mode consumers."],"exampleFix":"# before\nresp = await completion(tenant_id, agent_id, release=\"true\")\n\n# after (guard before calling)\ne, cvs = UserCanvasService.get_by_id(agent_id)\nif not UserCanvasVersionService.get_latest_released(agent_id):\n    raise ValueError(\"Agent has no published version; publish it or call without release=true\")\nresp = await completion(tenant_id, agent_id, release=\"true\")","handlingStrategy":"validation","validationCode":"if release_mode and not UserCanvasVersionService.get_latest_released(agent_id):\n    raise ValueError(\"Agent has no published version; publish first or run in draft mode\")","typeGuard":"def agent_published(agent_id: str) -> bool:\n    return bool(UserCanvasVersionService.get_latest_released(agent_id))","tryCatchPattern":"try:\n    cvs, dsl = UserCanvasService.get_agent_dsl_with_release(agent_id, release_mode=True)\nexcept PermissionError:\n    # not published yet — distinct from LookupError 'not found'\n    return jsonify(error=\"No published version\"), 409","preventionTips":["Catch PermissionError separately from LookupError: 409 vs 404 semantics.","Publish agents before wiring external consumers to release-mode endpoints.","Re-publish after deleting release versions."],"tags":["agent","release","publish","ragflow"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}