{"record":{"id":"619752d12bf344e5","repo":"discourse/discourse","slug":"blockcondition-validate-must-be-a-function-got","errorCode":null,"errorMessage":"blockCondition: \"validate\" must be a function, got ${typeof validateFn}.","messagePattern":"blockCondition: \"validate\" must be a function, got (.+?)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/discourse/app/blocks/conditions/decorator.ts","lineNumber":208,"sourceCode":"      `blockCondition: unknown config key(s): ${suggestions}. ` +\n        `Valid keys are: ${VALID_CONFIG_KEYS.join(\", \")}.`\n    );\n  }\n\n  // Validate args schema at decoration time (catches schema definition errors)\n  if (argsSchema && typeof argsSchema === \"object\") {\n    validateConditionArgsSchema(argsSchema, type);\n  }\n\n  // Validate constraints schema at decoration time\n  if (constraints) {\n    // Constraints reference args schema - validate they're compatible\n    validateConstraintsSchema(constraints, argsSchema, `Condition \"${type}\"`);\n  }\n\n  // Validate that validate is a function if provided\n  if (validateFn !== undefined && typeof validateFn !== \"function\") {\n    throw new Error(\n      `blockCondition: \"validate\" must be a function, got ${typeof validateFn}.`\n    );\n  }\n\n  // Freeze schema and compute derived validArgKeys\n  const frozenSchema: Readonly<Record<string, ArgSchema>> = Object.freeze({\n    ...argsSchema,\n  });\n  const frozenConstraints: Readonly<BlockConstraints> | undefined = constraints\n    ? Object.freeze({ ...constraints })\n    : undefined;\n  const argKeys: readonly string[] = Object.freeze(Object.keys(argsSchema));\n  const allKeys: readonly string[] =\n    sourceType !== \"none\" ? Object.freeze([...argKeys, \"source\"]) : argKeys;\n\n  return (TargetClass) => {\n    // Validate that the class extends BlockCondition\n    if (!(TargetClass.prototype instanceof BlockCondition)) {","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/discourse/discourse/blob/1b2d7253e854205d2c95c80b2c6a1cdd42e45059/frontend/discourse/app/blocks/conditions/decorator.ts#L190-L226","documentation":"Error \"blockCondition: \"validate\" must be a function, got ${typeof validateFn}.\" thrown in discourse/discourse.","triggerScenarios":"Thrown at frontend/discourse/app/blocks/conditions/decorator.ts:208 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"1b2d7253e854205d2c95c80b2c6a1cdd42e45059","analyzedAt":"2026-08-26T03:11:08.302Z","schemaVersion":2},"datasetVersion":"2026-08-26T07:17:17.940Z"}