{"record":{"id":"7dd555d383ac0d8c","repo":"ruvnet/ruflo","slug":"field-key-must-be-a-boolean","errorCode":null,"errorMessage":"field \"${key}\" must be a boolean","messagePattern":"field \"(.+?)\" must be a boolean","errorType":"validation","errorClass":"PodTemplateValidationError","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/business-pods/pod-schema.ts","lineNumber":112,"sourceCode":"  const v = parent[key];\n  if (typeof v !== 'string' || v.length === 0) {\n    throw new PodTemplateValidationError(`field \"${key}\" must be a non-empty string`, path);\n  }\n  return v;\n}\n\nfunction requireNumber(parent: Record<string, unknown>, key: string, path: string): number {\n  const v = parent[key];\n  if (typeof v !== 'number' || !Number.isFinite(v)) {\n    throw new PodTemplateValidationError(`field \"${key}\" must be a finite number`, path);\n  }\n  return v;\n}\n\nfunction requireBoolean(parent: Record<string, unknown>, key: string, path: string): boolean {\n  const v = parent[key];\n  if (typeof v !== 'boolean') {\n    throw new PodTemplateValidationError(`field \"${key}\" must be a boolean`, path);\n  }\n  return v;\n}\n\nfunction requireArray<T>(parent: Record<string, unknown>, key: string, path: string,\n                          itemValidator: (item: unknown, ipath: string) => T): T[] {\n  const v = parent[key];\n  if (!Array.isArray(v)) {\n    throw new PodTemplateValidationError(`field \"${key}\" must be an array`, path);\n  }\n  return v.map((item, idx) => itemValidator(item, `${path}/${key}[${idx}]`));\n}\n\nfunction validatePodAgent(item: unknown, path: string): PodAgent {\n  if (!isObject(item)) throw new PodTemplateValidationError('agent must be an object', path);\n  return {\n    role: requireString(item, 'role', path),\n    agentType: requireString(item, 'agentType', path),","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/business-pods/pod-schema.ts#L94-L130","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use bare JSON booleans: \"preferLocal\": true and \"preferLocalExecution\": false","Fix the YAML source: prefer_local: true (unquoted) before converting to JSON","If generating programmatically, ensure boolean values aren't stringified by the template engine","Validate in CI with validatePodTemplate to catch these before runtime"],"exampleFix":"// before\n{ \"preferLocal\": \"true\", \"preferLocalExecution\": \"false\" }\n// after\n{ \"preferLocal\": true, \"preferLocalExecution\": false }","handlingStrategy":"validation","validationCode":"function isStrictBooleanField(o: Record<string, unknown>, key: string): boolean {\n  return typeof o[key] === 'boolean';\n}\nif (!isStrictBooleanField(template, 'preferLocalExecution')) fail('preferLocalExecution must be true/false, unquoted');","typeGuard":"function isStrictBoolean(v: unknown): v is boolean {\n  return typeof v === 'boolean';\n}","tryCatchPattern":"try {\n  validatePodTemplate(template);\n} catch (e) {\n  if (e instanceof PodTemplateValidationError && e.message.includes('must be a boolean')) {\n    fail(`Use bare true/false at ${e.path} — strings like \"true\" are rejected`);\n  } else throw e;\n}","preventionTips":["Leave YAML booleans unquoted (prefer_local: true) before JSON conversion","Template engines that stringify values are the usual culprit — post-process with a boolean fixer","Check both agents[].preferLocal and top-level preferLocalExecution"],"tags":["pod","schema","validation","json","booleans"],"backgroundTag":"schema-validation-failed","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}