{"record":{"id":"8a83806dbabf8d80","repo":"bmad-code-org/BMAD-METHOD","slug":"async-validation-is-not-supported-by-clack-prompt","errorCode":null,"errorMessage":"Async validation is not supported by @clack/prompts. Please use synchronous validation.","messagePattern":"Async validation is not supported by @clack/prompts\\. Please use synchronous validation\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"tools/installer/prompts.js","lineNumber":701,"sourceCode":"    // Handle conditional questions via 'when' property\n    if (when !== undefined) {\n      const shouldAsk = typeof when === 'function' ? await when(answers) : when;\n      if (!shouldAsk) continue;\n    }\n\n    let answer;\n\n    switch (type) {\n      case 'input': {\n        // Note: @clack/prompts doesn't support async validation, so validate must be sync\n        answer = await text({\n          message,\n          default: typeof defaultValue === 'function' ? defaultValue(answers) : defaultValue,\n          validate: validate\n            ? (val) => {\n                const result = validate(val, answers);\n                if (result instanceof Promise) {\n                  throw new TypeError('Async validation is not supported by @clack/prompts. Please use synchronous validation.');\n                }\n                return result === true ? undefined : result;\n              }\n            : undefined,\n        });\n        break;\n      }\n\n      case 'confirm': {\n        answer = await confirm({\n          message,\n          default: typeof defaultValue === 'function' ? defaultValue(answers) : defaultValue,\n        });\n        break;\n      }\n\n      case 'list': {\n        answer = await select({","sourceCodeStart":683,"sourceCodeEnd":719,"githubUrl":"https://github.com/bmad-code-org/BMAD-METHOD/blob/b70486b9bdcb0a404d329e2a763b57964e7f1360/tools/installer/prompts.js#L683-L719","documentation":"Thrown (as TypeError) inside the input-prompt wrapper when a question's validate callback returns a Promise. @clack/prompts' text() calls validate synchronously per keystroke; the wrapper detects a Promise return and converts it to a TypeError so the failure is loud instead of silently passing validation (the Promise would never be awaited).","triggerScenarios":"Defining a prompt question with type:'input' and a validate function declared async or returning a Promise — e.g. validate: async (val) => await fs.pathExists(val).","commonSituations":"Migrating from inquirer (which supports async validate) to @clack/prompts; reusing an async validator across prompt libraries; validating against the filesystem/network inside the prompt.","solutions":["Make the validator synchronous: replace async with a sync function and use sync APIs (fs.pathExistsSync) or pre-computed state captured in closure.","If the check is inherently async, perform it before the prompt and pass the result in, or validate after the prompt returns.","Move expensive checks into a when predicate or a pre-prompt step that runs once."],"exampleFix":"// before\n//   { type: 'input', name: 'path', message: 'Path:',\n//     validate: async (val) => (await fs.pathExists(val)) || 'Not found' }\n//\n// after\n//   { type: 'input', name: 'path', message: 'Path:',\n//     validate: (val) => fs.pathExistsSync(val) || 'Not found' }","handlingStrategy":"validation","validationCode":"function assertSyncValidators(questions) {\n  for (const q of questions) {\n    if (q.type === 'input' && typeof q.validate === 'function' && q.validate.constructor.name === 'AsyncFunction') {\n      throw new Error(`Validator for '${q.name}' is async; @clack/prompts requires sync.`);\n    }\n  }\n}\nassertSyncValidators(questions);","typeGuard":"function isSyncValidator(fn) {\n  return typeof fn === 'function' && fn.constructor.name !== 'AsyncFunction';\n}","tryCatchPattern":"try {\n  answers = await getClack(questions);\n} catch (e) {\n  if (/Async validation is not supported/.test(e.message)) {\n    // rewrite the offending validator to be sync and retry, or pre-validate inputs\n  } else { throw e; }\n}","preventionTips":["Never declare prompt validate functions async when targeting @clack/prompts.","Pre-compute async-only data before the prompt and close over it.","Centralize validators in one module and lint for 'async' keyword on validate functions."],"tags":["prompts","clack","validation","async","input"],"backgroundTag":null,"analyzedSha":"b70486b9bdcb0a404d329e2a763b57964e7f1360","analyzedAt":"2026-08-13T01:21:12.247Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}