ruvnet/ruflo · error · PodTemplateValidationError

field "${key}" must be a boolean

Error message

field "${key}" must be a boolean

What it means

Pod template validator's requireBoolean() throws PodTemplateValidationError when a required boolean field is missing or not strictly a boolean. Covers agents[].preferLocal and preferLocalExecution. The check is typeof-based, so truthy/falsy values like 1, "true", or null are rejected.

Source

Thrown at v3/@claude-flow/cli/src/business-pods/pod-schema.ts:112

  const v = parent[key];
  if (typeof v !== 'string' || v.length === 0) {
    throw new PodTemplateValidationError(`field "${key}" must be a non-empty string`, path);
  }
  return v;
}

function requireNumber(parent: Record<string, unknown>, key: string, path: string): number {
  const v = parent[key];
  if (typeof v !== 'number' || !Number.isFinite(v)) {
    throw new PodTemplateValidationError(`field "${key}" must be a finite number`, path);
  }
  return v;
}

function requireBoolean(parent: Record<string, unknown>, key: string, path: string): boolean {
  const v = parent[key];
  if (typeof v !== 'boolean') {
    throw new PodTemplateValidationError(`field "${key}" must be a boolean`, path);
  }
  return v;
}

function requireArray<T>(parent: Record<string, unknown>, key: string, path: string,
                          itemValidator: (item: unknown, ipath: string) => T): T[] {
  const v = parent[key];
  if (!Array.isArray(v)) {
    throw new PodTemplateValidationError(`field "${key}" must be an array`, path);
  }
  return v.map((item, idx) => itemValidator(item, `${path}/${key}[${idx}]`));
}

function validatePodAgent(item: unknown, path: string): PodAgent {
  if (!isObject(item)) throw new PodTemplateValidationError('agent must be an object', path);
  return {
    role: requireString(item, 'role', path),
    agentType: requireString(item, 'agentType', path),

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Use bare JSON booleans: "preferLocal": true and "preferLocalExecution": false
  2. Fix the YAML source: prefer_local: true (unquoted) before converting to JSON
  3. If generating programmatically, ensure boolean values aren't stringified by the template engine
  4. Validate in CI with validatePodTemplate to catch these before runtime

Example fix

// before
{ "preferLocal": "true", "preferLocalExecution": "false" }
// after
{ "preferLocal": true, "preferLocalExecution": false }
Defensive patterns

Strategy: validation

Validate before calling

function isStrictBooleanField(o: Record<string, unknown>, key: string): boolean {
  return typeof o[key] === 'boolean';
}
if (!isStrictBooleanField(template, 'preferLocalExecution')) fail('preferLocalExecution must be true/false, unquoted');

Type guard

function isStrictBoolean(v: unknown): v is boolean {
  return typeof v === 'boolean';
}

Try / catch

try {
  validatePodTemplate(template);
} catch (e) {
  if (e instanceof PodTemplateValidationError && e.message.includes('must be a boolean')) {
    fail(`Use bare true/false at ${e.path} — strings like "true" are rejected`);
  } else throw e;
}

Prevention

When it happens

Trigger: validatePodTemplate() with "preferLocal": "true" (string), 1, 0, null, or the key omitted entirely. YAML-to-JSON conversion frequently produces "true"/"false" strings; the failing key name is included in the message.

Common situations: Templates maintained in YAML where booleans were quoted; JSON produced by templating engines (Jinja/Handlebars) that stringify values; users copying examples that used Yes/No.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/7dd555d383ac0d8c. Report an issue: GitHub.