agentscope-ai/agentscope · error · HTTPException

{kind.value.replace('_', ' ').title()} '{resource_id}' is re

Error message

{kind.value.replace('_', ' ').title()} '{resource_id}' is read-only for this viewer.

What it means

Thrown by the access-control service's resolve_for_edit when the viewer has at most read permission (ResourcePermission != EDIT) for the target resource. AgentScope's app layer distinguishes read-only viewers from editors; any mutation attempt on a resource the viewer can only see is rejected with HTTP 403. Team-sourced agent records are skipped as candidates, so only explicitly granted edit permission counts.

Source

Thrown at src/agentscope/app/_service/_access.py:505

        """
        own = await self._get_owned(kind, viewer_id, resource_id)
        if own is not None:
            return viewer_id, own

        for ref in await self._list_refs(viewer_id, kind):
            if ref.resource_id != resource_id:
                continue
            record = await self._get_owned(
                kind,
                ref.owner_id,
                ref.resource_id,
            )
            if record is None:
                continue
            if isinstance(record, AgentRecord) and record.source == "team":
                continue
            if ref.permission != ResourcePermission.EDIT:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN,
                    detail=(
                        f"{kind.value.replace('_', ' ').title()} "
                        f"'{resource_id}' is read-only for this viewer."
                    ),
                )
            return ref.owner_id, record
        raise self._not_found(kind, resource_id)

    # ------------------------------------------------------------------
    # Internals
    # ------------------------------------------------------------------

    async def _get_owned(
        self,
        kind: ResourceKind,
        owner_id: str,
        resource_id: str,

View on GitHub (pinned to e90f1c7592)

Solutions

  1. Have an owner/admin grant EDIT permission on that resource to the current viewer
  2. Perform the mutation with a user/token that already has edit rights
  3. In the UI, disable edit/delete actions when the resolved permission is not EDIT
  4. If you own the resource, check that you are authenticating as the owner account rather than a team viewer identity

Example fix

// before
await client.update_agent(agent_id="agent-123", ...)  # 403
# after: grant edit first (as owner/admin)
await admin_client.grant_permission(resource="agent", resource_id="agent-123", user_id=viewer_id, permission="EDIT")
await client.update_agent(agent_id="agent-123", ...)
Defensive patterns

Strategy: validation

Validate before calling

perm = await access_client.get_permission(kind="agent", resource_id=agent_id)
if perm != "EDIT":
    raise PermissionError(f"Viewer cannot modify {agent_id}; ask owner for EDIT")
await client.update_agent(agent_id=agent_id, ...)

Type guard

def can_edit(perm: str) -> bool:
    return perm == "EDIT"  # ResourcePermission.EDIT value

Try / catch

try:
    await client.update_agent(...)
except HTTPStatusError as e:
    if e.response.status_code == 403:
        prompt_user_for_edit_access(resource_id)
    else:
        raise

Prevention

When it happens

Trigger: Calling update_agent, delete_agent, update_credential, or delete_credential for a resource_id where the current user's permission reference is VIEW/READ. Commonly occurs for agents shared with a user as viewers or agents discovered via a team.

Common situations: A shared workspace where an admin granted 'view' instead of 'edit'; scripts written with an owner account but run with a collaborator token; UI hiding the edit/disable state so users click edit on read-only items; freshly issued API tokens with default viewer scope.

Related errors


AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28). Data as JSON: /api/errors/16382adba57aa4f4. Report an issue: GitHub.