infiniflow/ragflow · error · PermissionError

No available published version

Error message

No available published version

What it means

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'.

Source

Thrown at api/db/services/canvas_service.py:346

        tids = [t.tenant_id for t in UserTenantService.query(user_id=tenant_id)]
        if c["user_id"] == tenant_id:
            return True
        if c["user_id"] not in tids:
            return False
        if c["permission"] != TenantPermission.TEAM.value:
            return False
        return True

    @classmethod
    def get_agent_dsl_with_release(cls, agent_id, release_mode=False, tenant_id=None):
        e, cvs = cls.get_by_id(agent_id)
        if not e:
            raise LookupError("Agent not found.")

        if release_mode:
            released_version = UserCanvasVersionService.get_latest_released(agent_id)
            if not released_version:
                raise PermissionError("No available published version")
            dsl = released_version.dsl
        else:
            dsl = cvs.dsl

        if not isinstance(dsl, str):
            dsl = json.dumps(dsl, ensure_ascii=False)

        return cvs, dsl


async def completion(tenant_id, agent_id, session_id=None, **kwargs):
    query = kwargs.get("query", "") or kwargs.get("question", "")
    files = kwargs.get("files", [])
    inputs = kwargs.get("inputs", {})
    user_id = kwargs.get("user_id", "")
    chat_template_kwargs = kwargs.get("chat_template_kwargs")
    custom_header = kwargs.get("custom_header", "")
    release_mode = str(kwargs.get("release", "")).strip().lower()

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Publish (release) the agent first, then call with release mode.
  2. Or drop the release flag to run the current draft DSL.
  3. In clients, catch PermissionError separately and prompt 'agent not published yet'.
  4. After deleting releases, republish before re-enabling release-mode consumers.

Example fix

# before
resp = await completion(tenant_id, agent_id, release="true")

# after (guard before calling)
e, cvs = UserCanvasService.get_by_id(agent_id)
if not UserCanvasVersionService.get_latest_released(agent_id):
    raise ValueError("Agent has no published version; publish it or call without release=true")
resp = await completion(tenant_id, agent_id, release="true")
Defensive patterns

Strategy: validation

Validate before calling

if release_mode and not UserCanvasVersionService.get_latest_released(agent_id):
    raise ValueError("Agent has no published version; publish first or run in draft mode")

Type guard

def agent_published(agent_id: str) -> bool:
    return bool(UserCanvasVersionService.get_latest_released(agent_id))

Try / catch

try:
    cvs, dsl = UserCanvasService.get_agent_dsl_with_release(agent_id, release_mode=True)
except PermissionError:
    # not published yet — distinct from LookupError 'not found'
    return jsonify(error="No published version"), 409

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/d778e055d39372ee. Report an issue: GitHub.