hcengineering/platform · error

Mixin ${questions.mixin.QuestionMixin} not found for questio

Error message

Mixin ${questions.mixin.QuestionMixin} not found for question class ${questionClass._id}

What it means

getQuestionMixin verifies that a question class carries the QuestionMixin before casting to it via hierarchy.as(). If the resolved class does not have questions.mixin.QuestionMixin registered in the hierarchy, this error is thrown. It protects callers (e.g. mixin()) from treating a non-question class as a question and accessing question-specific mixin data that does not exist.

Source

Thrown at plugins/questions-resources/src/utils/getQuestionMixin.ts:16

//
// Copyright @ 2024 Hardcore Engineering Inc.
//

import type { Answer, Question, QuestionMixin } from '@hcengineering/questions'
import type { Class, Ref } from '@hcengineering/core'
import { getClient } from '@hcengineering/presentation'
import questions from '../plugin'

export function getQuestionMixin<Q extends Question<any>> (
  questionClassRef: Ref<Class<Q>>
): QuestionMixin<Q, Answer<Q, unknown>> {
  const hierarchy = getClient().getHierarchy()
  const questionClass = hierarchy.getClass<Q>(questionClassRef)
  if (!hierarchy.hasMixin(questionClass, questions.mixin.QuestionMixin)) {
    throw new Error(`Mixin ${questions.mixin.QuestionMixin} not found for question class ${questionClass._id}`)
  }
  return hierarchy.as(questionClass, questions.mixin.QuestionMixin)
}

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Ensure the question class definition includes QuestionMixin (mixins: questions.mixin.QuestionMixin) when registering it in the model.
  2. Verify the classRef passed to getQuestionMixin actually points to a question class; log/inspect hierarchy.getClass(questionClassRef)._class.
  3. Re-run model/migration upgrades so the deployed hierarchy includes the mixin for all question classes.
  4. Guard the call site: use hierarchy.hasMixin(class, questions.mixin.QuestionMixin) before requesting the mixin and handle the negative case.

Example fix

// before: register subclass without mixin
export const MyQuestion = classify(MyQuestionId, 'question', ...) // no QuestionMixin

// after
export const MyQuestion = classify(MyQuestionId, 'question', 'Question', {
  mixins: [questions.mixin.QuestionMixin]
})
Defensive patterns

Strategy: validation

Validate before calling

function ensureQuestionMixin<Q extends Question<any>>(classRef: Ref<Class<Q>>): boolean {
  const hierarchy = getClient().getHierarchy()
  const cls = hierarchy.getClass<Q>(classRef)
  return hierarchy.hasMixin(cls, questions.mixin.QuestionMixin)
}
// guard: if (!ensureQuestionMixin(classRef)) { /* handle non-question class */ }

Type guard

function isQuestionClass<Q extends Question<any>>(classRef: Ref<Class<Q>>): boolean {
  const hierarchy = getClient().getHierarchy()
  if (!hierarchy.getClasses().some((c) => c._id === classRef)) return false
  return hierarchy.hasMixin(hierarchy.getClass<Q>(classRef), questions.mixin.QuestionMixin)
}

Try / catch

let question: QuestionMixin<Question<any>, Answer<Question<any>, unknown>>
try {
  question = getQuestionMixin(classRef)
} catch (err) {
  if (err instanceof Error && err.message.includes('not found for question class')) {
    console.error('Class is not registered as a question:', classRef)
    return // or fallback path
  }
  throw err
}

Prevention

When it happens

Trigger: Calling getQuestionMixin (directly or via mixin()) with a Ref<Class<Q>> that resolves to a class created without QuestionMixin — e.g. a subclass registered in the hierarchy without mixing in questions.mixin.QuestionMixin, a wrong/typo'd class reference, or a class from an unrelated plugin passed in.

Common situations: Custom question subclasses added to the model without applying the mixin; plugin version mismatch where an older model snapshot lacks the mixin; passing the answer/result class instead of the question class; migration where classes were re-created without mixin data.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/f6478d7ce9daabf9. Report an issue: GitHub.