{"record":{"id":"3a281560a14e741b","repo":"usestrix/strix","slug":"scope-id-and-scope-name-required-for-update","errorCode":null,"errorMessage":"scope_id and scope_name required for update","messagePattern":"scope_id and scope_name required for update","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"strix/tools/proxy/caido_api.py","lineNumber":528,"sourceCode":") -> Any:\n    if action == \"list\":\n        result = await scope_list(client)\n    elif action == \"get\":\n        if not scope_id:\n            raise ValueError(\"scope_id required for get\")\n        result = await scope_get(client, scope_id)\n    elif action == \"create\":\n        if not scope_name:\n            raise ValueError(\"scope_name required for create\")\n        result = await scope_create(\n            client,\n            name=scope_name,\n            allowlist=allowlist,\n            denylist=denylist,\n        )\n    elif action == \"update\":\n        if not scope_id or not scope_name:\n            raise ValueError(\"scope_id and scope_name required for update\")\n        result = await scope_update(\n            client,\n            scope_id,\n            name=scope_name,\n            allowlist=allowlist,\n            denylist=denylist,\n        )\n    elif action == \"delete\":\n        if not scope_id:\n            raise ValueError(\"scope_id required for delete\")\n        await scope_delete(client, scope_id)\n        result = {\"deleted\": scope_id}\n    else:\n        raise ValueError(f\"Unknown action: {action}\")\n    return result\n\n\n_SITEMAP_ROOTS_QUERY = \"\"\"","sourceCodeStart":510,"sourceCodeEnd":546,"githubUrl":"https://github.com/usestrix/strix/blob/85513391305171ecc6faffe03da4a8bda5e3febb/strix/tools/proxy/caido_api.py#L510-L546","documentation":"For action='update' the Caido scope dispatcher requires both scope_id (which scope to update) and scope_name (the new name); missing either raises ValueError. Update is a full identification of the target plus its replacement name, not a partial patch selector.","triggerScenarios":"Calling action='update' with only scope_id (renaming assumed implicit) or only scope_name (target assumed inferred). Both fields must be present and non-empty.","commonSituations":"Agent or script reuses the create-style call for updates; caller tries to update filters by name without knowing the id; empty string from an env/variable expansion.","solutions":["Run action='list' to resolve the scope's id.","Call action='update' with both scope_id and the new scope_name (plus allowlist/denylist if changing filters).","If you only wanted filter changes, still supply scope_name — pass the existing name unchanged."],"exampleFix":"# before\nscope(client, \"update\", scope_id=sid, allowlist=[...])\n\n# after\nscope(client, \"update\", scope_id=sid, scope_name=\"target\", allowlist=[...])","handlingStrategy":"validation","validationCode":"def scope_id_by_name(client, name: str) -> str:\n    for s in scope(client, \"list\"):\n        if s.get(\"name\") == name:\n            return s[\"id\"]\n    raise LookupError(name)\n\nsid = scope_id_by_name(client, current_name)\nscope(client, \"update\", scope_id=sid, scope_name=new_name, allowlist=al)","typeGuard":null,"tryCatchPattern":"try:\n    scope(client, \"update\", scope_id=sid, scope_name=name, allowlist=al)\nexcept ValueError as exc:\n    if \"required for update\" in str(exc):\n        sid = scope_id_by_name(client, name)\n        scope(client, \"update\", scope_id=sid, scope_name=name, allowlist=al)\n    else:\n        raise","preventionTips":["For updates, always carry both the resolved id and (possibly unchanged) name.","Wrap the dispatcher with a name->id resolver so callers never guess ids.","Remember update replaces the name — pass the existing name if only filters change."],"tags":["proxy","caido","scope","validation"],"backgroundTag":null,"analyzedSha":"85513391305171ecc6faffe03da4a8bda5e3febb","analyzedAt":"2026-08-15T05:03:57.275Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}