ruvnet/ruflo · error
worker policy denied: ${decision.reason ?? 'unknown reason'}
Error message
worker policy denied: ${decision.reason ?? 'unknown reason'} What it means
Before spawning each worker, authorizeWorker shells out to `npx ruflo@latest policy evaluate` with the worker's identity, a swarm.worker.spawn action over its worktree/project path, and its capability envelope. The policy engine returns a decision object; any outcome other than enforcedOutcome === 'allowed' aborts the spawn with this error, including the engine's reason when present. Note this error specifically means the engine answered with a non-allowed decision — a missing ruflo binary or non-JSON output fails differently (command failure or JSON.parse error).
Source
Thrown at v3/@claude-flow/codex/src/dual-mode/orchestrator.ts:543
type: 'swarm.worker.spawn',
resource: worker.worktreePath ?? this.config.projectPath,
tool: worker.platform,
concurrency: 1,
network: false,
destructive: false,
},
context: {
metadata: { childCapabilityEnvelope: envelope },
},
};
const raw = await this.runCommand(
'npx',
['ruflo@latest', 'policy', 'evaluate', JSON.stringify(request)],
this.config.projectPath,
);
const decision = JSON.parse(raw) as { enforcedOutcome?: string; reason?: string };
if (decision.enforcedOutcome !== 'allowed') {
throw new Error(`worker policy denied: ${decision.reason ?? 'unknown reason'}`);
}
worker.capabilityEnvelope = envelope;
}
private defaultWorkerEnvelope(worker: WorkerConfig): WorkerCapabilityEnvelope {
return {
actions: ['*'],
resources: ['*'],
tools: ['*'],
maxConcurrency: 1,
network: false,
destructive: false,
delegationDepth: 0,
expiresAt: Date.now() + this.config.timeout,
};
}
private resolveWorkerEnvelope(worker: WorkerConfig): WorkerCapabilityEnvelope {View on GitHub (pinned to fa13ee4ad6)
Solutions
- Read the reason embedded in the message — it comes straight from the policy decision and usually names the failing rule or capability
- Run `npx ruflo policy status` and `npx ruflo policy verify` in the project to inspect the active mode and rule set
- Shrink the worker's capabilityEnvelope (no network/destructive, fewer actions/tools) or point the worker at a resource path the policy grants for its role
- If the denial is correct, keep the policy and cancel dependent sibling work instead of trying to bypass the decision point
Defensive patterns
Strategy: try-catch
Validate before calling
import { spawnSync } from 'node:child_process';
function previewPolicyDecision(projectPath: string, request: object): { enforcedOutcome?: string; reason?: string } | null {
const res = spawnSync('npx', ['ruflo@latest', 'policy', 'evaluate', JSON.stringify(request)],
{ cwd: projectPath, encoding: 'utf8' });
if (res.status !== 0) return null;
try { return JSON.parse(res.stdout); } catch { return null; }
} Try / catch
try { await orchestrator.run(...); } catch (error) { if (error instanceof Error && error.message.startsWith('worker policy denied')) { const reason = error.message.slice('worker policy denied: '.length); /* cancel dependent siblings, surface reason to user */ } throw error; } — never catch-and-continue past a policy denial. Prevention
- Run `npx ruflo policy status` before starting a swarm in policy-governed repos
- Keep worker envelopes minimal so the spawn action stays inside policy grants
- Treat 'worker policy denied' as an authorization signal: cancel dependent work, do not retry the same request
When it happens
Trigger: A Ruflo policy in enforce mode denies swarm.worker.spawn for the worker's role, resource path, or platform; the requested capability envelope exceeds what policy grants to the principal; or the engine emits a deny/observe outcome with no reason field (message then shows 'unknown reason').
Common situations: Running a swarm in a repo whose policy config protects the paths the worker writes to; a session principal (CLAUDE_FLOW_PRINCIPAL_ID) not covered by any allow rule; upgrading ruflo so previously-tolerated actions now require explicit grants.
Related errors
- approval issuance requires an authenticated human identity a
- policy-${decision.enforcedOutcome}:${decision.reason}; recei
- policy administration requires an authenticated user context
- self-approval-forbidden
- untrusted-approval-issuer
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/508a14ad38632346.
Report an issue: GitHub.