ruvnet/ruflo · error · PodTemplateValidationError
pod-template at ${path}: name must be lowercase-kebab (e.g.
Error message
pod-template at ${path}: name must be lowercase-kebab (e.g. "sales") What it means
Thrown by validatePodTemplate() when the 'name' field fails the regex /^[a-z][a-z0-9-]*$/. The name must start with a lowercase letter and contain only lowercase letters, digits, and hyphens (lowercase-kebab). This name is canonical and matches the BBS roomId, so strict casing is enforced.
Source
Thrown at v3/@claude-flow/cli/src/business-pods/pod-schema.ts:193
// time. We only catch obviously malformed values here.
const CRON_RE = /^([\d*/,\-]+\s+){4,5}[\d*/,\-]+$/;
/**
* Validate `json` and return a typed `PodTemplate`. Throws
* `PodTemplateValidationError` with a JSON-pointer-style path on failure.
*
* Used by:
* - `business_pod_validate` MCP tool — returns the error verbatim
* - `pod-tick.mjs` — pre-flight check before any pod execution
* - any external schema-loader that wants typed templates
*/
export function validatePodTemplate(json: unknown): PodTemplate {
if (!isObject(json)) {
throw new PodTemplateValidationError('pod-template must be a JSON object', '/');
}
const name = requireString(json, 'name', '/');
if (!/^[a-z][a-z0-9-]*$/.test(name)) {
throw new PodTemplateValidationError('name must be lowercase-kebab (e.g. "sales")', '/');
}
const displayName = requireString(json, 'displayName', '/');
const roomId = requireString(json, 'roomId', '/');
if (!/^[A-Za-z0-9_.\-:/@#]+$/.test(roomId)) {
throw new PodTemplateValidationError(
'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,View on GitHub (pinned to 6b01dc5a68)
Solutions
- Change the 'name' field to lowercase-kebab (e.g. 'sales', 'lead-gen', 'hr-onboarding')
- Ensure the name starts with a lowercase letter a-z, not a digit or hyphen
- Replace any underscores with hyphens
Example fix
// before
{ "name": "Sales_Pipeline", ... }
// after
{ "name": "sales-pipeline", ... } Defensive patterns
Strategy: validation
Validate before calling
const NAME_RE = /^[a-z][a-z0-9-]*$/;
function isValidPodName(name: string): boolean {
return NAME_RE.test(name);
}
if (!isValidPodName(template.name)) {
throw new Error('name must be lowercase-kebab');
} Type guard
function isLowercaseKebab(s: string): boolean {
return /^[a-z][a-z0-9-]*$/.test(s);
} Try / catch
try {
validatePodTemplate(json);
} catch (e) {
if (e instanceof PodTemplateValidationError && e.message.includes('name must be lowercase-kebab')) {
// Fix the name field and retry
}
} Prevention
- Use only lowercase letters, digits, and hyphens for the 'name' field
- Start the name with a lowercase letter, never a digit or hyphen
- Reserve uppercase and spaces for 'displayName'
When it happens
Trigger: The pod-template JSON has a 'name' value like 'Sales', 'sales_pod', '1sales', '-sales', or 'SALES'. Any uppercase character, underscore, leading digit, or leading hyphen triggers this error.
Common situations: A copy-pasted display name was accidentally used for the machine-readable 'name' field; a pod template was authored with CamelCase or snake_case naming conventions from another system.
Related errors
- 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
- pod-template at ${path}: agent must be an object
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/47078cc4c0a5afbb.
Report an issue: GitHub.