ruvnet/ruflo · error · PodTemplateValidationError
pod-template at ${path}: allowedMcpTools must have ≥1 entry
Error message
pod-template at ${path}: allowedMcpTools must have ≥1 entry What it means
Thrown by validatePodTemplate() when the allowedMcpTools array is present and all entries are valid strings, but the array has zero entries. A pod must allow at least one MCP tool — an empty allow-list means agents cannot perform any external actions.
Source
Thrown at v3/@claude-flow/cli/src/business-pods/pod-schema.ts:217
'roomId may only contain [A-Za-z0-9_.\\-:/@#]',
'/',
);
}
const agents = requireArray(json, 'agents', '/', validatePodAgent);
if (agents.length === 0) {
throw new PodTemplateValidationError('agents must have ≥1 entry', '/');
}
const allowedMcpTools = requireArray(json, 'allowedMcpTools', '/', (t, tp) => {
if (typeof t !== 'string' || t.length === 0) {
throw new PodTemplateValidationError(
'allowedMcpTools entries must be non-empty strings',
tp,
);
}
return t;
});
if (allowedMcpTools.length === 0) {
throw new PodTemplateValidationError('allowedMcpTools must have ≥1 entry', '/');
}
const bench = validatePodBench(json.bench, '/bench');
const piiPolicy = requireString(json, 'piiPolicy', '/');
if (!PII_POLICIES.includes(piiPolicy as PiiPolicy)) {
throw new PodTemplateValidationError(
`piiPolicy must be one of: ${PII_POLICIES.join(', ')}`,
'/',
);
}
const budgetUsdMonthly = requireNumber(json, 'budgetUsdMonthly', '/');
if (budgetUsdMonthly < 0) {
throw new PodTemplateValidationError('budgetUsdMonthly must be ≥0', '/');
}
const budgetUsdPerRun = requireNumber(json, 'budgetUsdPerRun', '/');
if (budgetUsdPerRun < 0) {
throw new PodTemplateValidationError('budgetUsdPerRun must be ≥0', '/');
}
if (budgetUsdMonthly > 0 && budgetUsdPerRun > budgetUsdMonthly) {View on GitHub (pinned to 6b01dc5a68)
Solutions
- Add at least one MCP tool name to the allowedMcpTools array (e.g. 'memory_search', 'task_create')
- Review which MCP tools the pod's agents genuinely need and add them
Example fix
// before
{ "allowedMcpTools": [] }
// after
{ "allowedMcpTools": ["memory_search", "hooks_route"] } Defensive patterns
Strategy: validation
Validate before calling
if (!Array.isArray(template.allowedMcpTools) || template.allowedMcpTools.length === 0) {
throw new Error('allowedMcpTools must have at least one entry');
} Type guard
function hasAllowedMcpTools(template: unknown): boolean {
return typeof template === 'object' && template !== null &&
Array.isArray((template as Record<string, unknown>).allowedMcpTools) &&
((template as Record<string, unknown>).allowedMcpTools as unknown[]).length > 0;
} Try / catch
try {
validatePodTemplate(json);
} catch (e) {
if (e instanceof PodTemplateValidationError && e.message.includes('allowedMcpTools must have')) {
// Add at least one MCP tool name
}
} Prevention
- Every pod must allow at least one MCP tool — an empty allow-list is invalid
- Common safe defaults: 'memory_search', 'task_create', 'hooks_route'
- Review the pod's agents to determine which tools they need
When it happens
Trigger: The pod-template JSON has "allowedMcpTools": [] — a valid but empty array. Each entry passed the item validator (there are none), then the length check fails.
Common situations: All tool entries were removed during a security tightening pass but none were kept; the template was copied from a minimal example that omitted the tools list.
Related errors
- pod-template at ${path}: allowedMcpTools entries must be non
- pod-template at ${path}: field "${key}" must be a non-empty
- pod-template at ${path}: field "${key}" must be a finite num
- pod-template at ${path}: field "${key}" must be a boolean
- pod-template at ${path}: field "${key}" must be an array
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/74862f49aeb279f1.
Report an issue: GitHub.