{"record":{"id":"069541358e5ef798","repo":"ruvnet/ruflo","slug":"policy-state-lock-timeout","errorCode":null,"errorMessage":"policy-state-lock-timeout","messagePattern":"policy-state-lock-timeout","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/services/policy-runtime.ts","lineNumber":63,"sourceCode":"\nasync function acquireLock(lockPath: string): Promise<() => void> {\n  const started = Date.now();\n  while (Date.now() - started < LOCK_WAIT_MS) {\n    try {\n      const fd = openSync(lockPath, 'wx', 0o600);\n      writeFileSync(fd, JSON.stringify({ pid: process.pid, acquiredAt: Date.now() }));\n      closeSync(fd);\n      return () => {\n        try { unlinkSync(lockPath); } catch { /* already released */ }\n      };\n    } catch {\n      try {\n        if (Date.now() - statSync(lockPath).mtimeMs > LOCK_STALE_MS) unlinkSync(lockPath);\n      } catch { /* another process changed the lock */ }\n      await sleep(10);\n    }\n  }\n  throw new Error('policy-state-lock-timeout');\n}\n\nfunction writeJsonAtomic(file: string, value: unknown): void {\n  mkdirSync(dirname(file), { recursive: true, mode: 0o700 });\n  const temporary = `${file}.${process.pid}.${randomUUID()}.tmp`;\n  writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600 });\n  renameSync(temporary, file);\n}\n\nfunction trustPaths(projectRoot: string): { key: string; anchor: string } {\n  const trustRoot = join(userInfo().homedir, '.config', 'ruflo', 'policy-trust');\n  const projectId = createHash('sha256').update(realpathSync(projectRoot)).digest('hex');\n  const dir = join(trustRoot, projectId);\n  return { key: join(dir, 'anchor.key'), anchor: join(dir, 'state.anchor.json') };\n}\n\nfunction trustKey(projectRoot: string, create: boolean): Buffer | undefined {\n  const { key } = trustPaths(projectRoot);","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/services/policy-runtime.ts#L45-L81","documentation":"acquireLock gives up after LOCK_WAIT_MS of contended exclusive-create attempts on the policy state lock file; stale locks older than LOCK_STALE_MS are broken automatically, so this signals live contention or an unbreakable lock.","triggerScenarios":"Thrown at v3/@claude-flow/cli/src/services/policy-runtime.ts:63 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry acquiring the policy state lock later","Find and stop the process holding the policy state lock"],"exampleFix":"Retry the policy operation; if the lock timeout persists, check for a stuck policy-state lock holder and restart the runtime.","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}