{"record":{"id":"6d552ed3b2374a88","repo":"usestrix/strix","slug":"scope-id-required-for-delete","errorCode":null,"errorMessage":"scope_id required for delete","messagePattern":"scope_id required for delete","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"strix/tools/proxy/caido_api.py","lineNumber":538,"sourceCode":"        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 = \"\"\"\nquery GetSitemapRoots($scopeId: ID) {\n    sitemapRootEntries(scopeId: $scopeId) {\n        edges { node {\n            id kind label hasDescendants\n            metadata { ... on SitemapEntryMetadataDomain { isTls port } }\n            request { method path response { statusCode } }\n        } }\n        count { value }\n    }\n}","sourceCodeStart":520,"sourceCodeEnd":556,"githubUrl":"https://github.com/usestrix/strix/blob/85513391305171ecc6faffe03da4a8bda5e3febb/strix/tools/proxy/caido_api.py#L520-L556","documentation":"For action='delete' the Caido scope dispatcher requires scope_id; a missing/empty id raises ValueError before calling scope_delete. Deletion is by immutable id, not by name, to avoid ambiguity.","triggerScenarios":"Calling action='delete' with only a scope_name, or with an empty scope_id. The handler refuses rather than guessing which scope to remove.","commonSituations":"Agent attempts delete-by-name; id variable unset in scripts; copy-paste from a create call that used names only.","solutions":["Run action='list' to get the exact scope id.","Call action='delete' with that scope_id.","Confirm the id before deleting — the operation is destructive and immediate once issued."],"exampleFix":"# before\nscope(client, \"delete\", scope_name=\"old-scope\")\n\n# after\nsid = scope(client, \"list\")[0][\"id\"]\nscope(client, \"delete\", scope_id=sid)","handlingStrategy":"validation","validationCode":"def delete_scope_by_id(client, scope_id: str | None) -> dict:\n    if not scope_id:\n        raise ValueError(\"scope_id required for delete\")\n    return scope(client, \"delete\", scope_id=scope_id)\n\n# resolve before deleting, never delete by name\nsid = next(s[\"id\"] for s in scope(client, \"list\") if s[\"name\"] == \"old\")","typeGuard":null,"tryCatchPattern":"try:\n    scope(client, \"delete\", scope_id=sid)\nexcept ValueError as exc:\n    if \"scope_id required for delete\" in str(exc):\n        raise SystemExit(\"refusing to delete without an explicit id\") from exc\n    raise","preventionTips":["Delete is destructive — always resolve the id from a fresh 'list' first.","Never accept a name-only delete in wrappers; keep the id mandatory.","Log the id being deleted for auditability."],"tags":["proxy","caido","scope","validation","destructive"],"backgroundTag":null,"analyzedSha":"85513391305171ecc6faffe03da4a8bda5e3febb","analyzedAt":"2026-08-15T05:03:57.275Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}