Skip to content

fix(quiz): fix grading bugs causing correct answers to be marked wrong#1064

Open
karan033-cybertech wants to merge 3 commits into
vicharanashala:mainfrom
karan033-cybertech:fix/quiz-grading-bugs
Open

fix(quiz): fix grading bugs causing correct answers to be marked wrong#1064
karan033-cybertech wants to merge 3 commits into
vicharanashala:mainfrom
karan033-cybertech:fix/quiz-grading-bugs

Conversation

@karan033-cybertech

Copy link
Copy Markdown

Problem — Closes #714

Three bugs were causing correct quiz answers to be marked wrong.

Bug 1 — SOLQuestionRenderer: shuffle lost on parameterized questions

When parameterMap was present, shuffled options were overwritten with
unshuffled lotItems, causing index mismatch between what student saw
and what grader checked.

Fix: Map over shuffledLotItems instead of lotItems.

Bug 2 — DESQuestionGrader: blank answers got full marks

Placeholder grading awarded Math.round(this.question.points) to every
descriptive answer including blank submissions.

Fix: Award score: 0 until real LLM grading is integrated.

Bug 3 — quiz.tsx: selected answers silently dropped

For SELECT_MANY_IN_LOT, if _id conversion failed, fallback
index.toString() was immediately filtered out — silently dropping
the student's selection before submission.

Fix: Detect failures early, log warning, skip submission instead
of sending corrupted partial answer set.

Files changed

  • backend/src/modules/quizzes/question-processing/renderers/SOLQuestionRenderer.ts
  • backend/src/modules/quizzes/question-processing/graders/DESQuestionGrader.ts
  • frontend/src/components/quiz.tsxS

Three separate bugs were causing correct quiz answers to be evaluated
incorrectly:

1. SOLQuestionRenderer: parameterized questions lost their shuffle
   when processing text tags — shuffledLotItems was overwritten with
   lotItems (unshuffled), causing option index mismatch between what
   student saw and what grader compared against. Fixed by mapping over
   shuffledLotItems instead of lotItems.

2. DESQuestionGrader: placeholder grading awarded full question points
   (Math.round(this.question.points)) to every descriptive answer
   including blank submissions. Fixed to award 0 score until real
   LLM grading is integrated.

3. quiz.tsx SELECT_MANY_IN_LOT: when a lotItem _id failed to convert
   from buffer to hex, the fallback returned index.toString() which
   was then silently filtered out by .filter(id => !id.match(/digit/)).
   This caused valid selected answers to be dropped before submission,
   resulting in incorrect grading. Fixed to detect conversion failures
   early and skip the whole submission rather than sending a corrupted
   partial answer set.

Fixes vicharanashala#714
When a lotItem _id failed to convert from buffer to hex, the fallback
returned index.toString() which was silently filtered out by
.filter(id => !id.match(/digit/)). This caused valid selected answers
to be dropped before submission, resulting in incorrect grading.

Fixed to detect conversion failures early and skip the whole submission
rather than sending a corrupted partial answer set.

Fixes vicharanashala#714
@github-actions github-actions Bot added frontend Changes to the frontend of the project backend labels Jun 7, 2026

@aloktripathi1 aloktripathi1 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of the three fixes have tests. Bug 1 and Bug 2 are deterministic and seem straightforward to unit test. Worth adding before merging?

// TODO: Integrate with LLM-based evaluation engine later
// This is a dummy placeholder response
return {
status: 'PARTIAL',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning status: 'PARTIAL' with score: 0 seems contradictory. PARTIAL
usually implies some credit was earned. Would it make more sense to use
'INCORRECT' here or introduce a 'PENDING' status to signal the answer
is waiting for LLM grading?

Comment thread frontend/src/components/quiz.tsx Outdated
if (resolvedIds.every(id => id !== null)) {
saveAnswer.lotItemIds = resolvedIds as string[];
} else {
console.error(`[quiz] One or more selected answers could not be resolved for question ${question.id}. Skipping submission for this question.`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If any ID conversion fails, the entire question submission is skipped.
If a student selects 5 answers and 1 fails, they lose all 5.
Would it be better to submit only the successfully resolved IDs instead
of skipping the whole question? The console.error is not visible to the
student either, so they would have no idea their answer was not saved.

- DESQuestionGrader: change status from PARTIAL to INCORRECT
  since score is 0 and no credit is awarded
- quiz.tsx: submit partially resolved IDs instead of skipping
  entire question when some _id conversions fail
@karan033-cybertech

Copy link
Copy Markdown
Author

None of the three fixes have tests. Bug 1 and Bug 2 are deterministic and seem straightforward to unit test. Worth adding before merging?

Thanks for the review @aloktripathi1! Addressed all three points in the latest commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend frontend Changes to the frontend of the project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Correct answers evaluated as wrong

2 participants