{"record":{"id":"8935e272b40ab001","repo":"denoland/deno","slug":"restore-test-permissions-token-does-not-match-the","errorCode":null,"errorMessage":"restore test permissions token does not match the stored token","messagePattern":"restore test permissions token does not match the stored token","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/ops/bench.rs","lineNumber":83,"sourceCode":"  }\n\n  state.put::<PermissionsHolder>(PermissionsHolder(token, parent_permissions));\n\n  // NOTE: This call overrides current permission set for the worker\n  state.put::<PermissionsContainer>(worker_permissions);\n\n  Ok(token)\n}\n\n#[op2]\npub fn op_restore_test_permissions(\n  state: &mut OpState,\n  #[serde] token: Uuid,\n) -> Result<(), JsErrorBox> {\n  match state.try_take::<PermissionsHolder>() {\n    Some(permissions_holder) => {\n      if token != permissions_holder.0 {\n        panic!(\n          \"restore test permissions token does not match the stored token\"\n        );\n      }\n\n      let permissions = permissions_holder.1;\n      state.put::<PermissionsContainer>(permissions);\n      Ok(())\n    }\n    _ => Err(JsErrorBox::generic(\"no permissions to restore\")),\n  }\n}\n\nstatic NEXT_ID: AtomicUsize = AtomicUsize::new(0);\n\n#[allow(clippy::too_many_arguments, reason = \"op\")]\n#[op2]\nfn op_register_bench(\n  state: &mut OpState,","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/ops/bench.rs#L65-L101","documentation":"Panic in the op_restore_test_permissions op (cli/ops/bench.rs) backing `deno bench`. Each pledge returns a random UUID token stored with the saved permissions; restore must present the matching token. If the caller passes a token different from the one currently stored (stale token from an earlier pledge, regenerated token, or cross-worker mix-up), the op panics rather than restoring the wrong permissions.","triggerScenarios":"Calling op_restore_test_permissions with a UUID that is not the token returned by the most recent op_pledge_test_permissions call in the same worker — e.g. reusing a token after a second pledge replaced the stored holder.","commonSituations":"Custom bench-harness forks caching tokens across pledge cycles; concurrent paths in harness code both trying to restore; copy-paste of harness snippets with hardcoded/old tokens. Not reachable through normal Deno.bench() usage.","solutions":["Propagate the exact token returned by the pledge call to the matching restore call (keep it in a local variable, single owner)","Guarantee one restore per pledge, in a finally block, with no interleaving pledges","If stock `deno bench` triggers this, file a Deno issue with the reproduction"],"exampleFix":"// before\nconst t = pledge(args);\nrestore('00000000-0000-0000-0000-000000000000'); // wrong token\n// after\nconst t = pledge(args);\ntry { runBench(); } finally { restore(t); }","handlingStrategy":"validation","validationCode":"// keep exactly one live token and reuse it for the matching restore\nlet liveToken = null;\nfunction pledge(args) { liveToken = pledgeOp(args); return liveToken; }\nfunction restore(token) {\n  if (token !== liveToken) throw new Error('stale pledge token; refusing to call restore');\n  restoreOp(token); liveToken = null;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store the pledge token in a single local scope and pass it to exactly one restore","Never cache tokens across pledge cycles or share them between workers"],"tags":["permissions","bench","token","internal-ops","panic"],"backgroundTag":"token-mismatch","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}