Skip to content

fix: submit_problem saving history before submission guards - #39015

Draft
shadinaif wants to merge 1 commit into
openedx:masterfrom
shadinaif:shadinaif/fix-studentmodulehistory
Draft

fix: submit_problem saving history before submission guards#39015
shadinaif wants to merge 1 commit into
openedx:masterfrom
shadinaif:shadinaif/fix-studentmodulehistory

Conversation

@shadinaif

@shadinaif shadinaif commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

WIP: related work in xblocks-contrib is needed

Description

_BuiltInProblemBlock.submit_problem (aka ProblemBlock.submit_problem) records the submitted answer into student_answers_history before the submission guards run, so rejected submissions are still recorded in history, while attempts correctly stays put. Each of those submissions also saves the block, writing a full courseware_studentmodulehistory row that carries the whole list, so the history table grows exponentially when too many rejected submissions are posted for the same problem.

Only the guards that return are affected: the xqueue waittime, submission_wait_seconds, and the StudentInputError / ResponseError / LoncapaProblemError branch. closed() and the unreset guard raise, so
nothing was ever persisted through them.

Fix. Move the append inside the try, immediately after grade_answers() returns. Only graded submissions
are recorded, the two lists stay in step, and the two return guards now leave the request with no dirty fields
at all, and no StudentModule write and no history row.

Operators benefit; learners see no change, since legitimate submissions are recorded exactly as before. No UI change, no configuration change, no migration.

Supporting information

The defect was introduced in this PR (see xmodule/capa_block.py line 1755), and there is no explanation why the history append self.student_answers_history.append(answers_without_files)` was made way before the other update statements

If there is a legit reason for the location of the append statement; then we must find another code fix for the bug. It is a bug to save history of rejected submissions especially when no reject reason is saved anywhere

Real Example

This is an observation from a production instance. An exam that was configured to require two hours between attempts was targeted by bots re-submitting every five seconds. That produced 1400+ history rows for submissions that were never graded, inflating both courseware_studentmodule and courseware_studentmodulehistory for no reason. There is no reason to retain those submissions!

On the other hand, detecting the abuse is a separate concern and is unaffected by this change: the submissions still show up in the tracking logs whether or not they are kept as learner state.

Testing instructions

Automated

  • pytest xmodule/tests/test_capa_block.py -k "answer_history or histories_stay_aligned"
  • pytest xmodule/tests/test_delay_between_attempts.py
  • Before the fix: all three new tests fail. After the fix: all three pass.

Manual: submissions rejected by the wait timer

  1. Create a Problem component, set Timer Between Attempts to 120 seconds, and allow multiple attempts.
  2. As a learner, submit a correct answer.
  3. Submit again immediately and confirm the "You must wait at least..." message appears.
  4. Repeat step 3 several times.
  5. Open Staff Debug Info - Submission History for that learner and problem.
    • Before the fix: each rejected submission added a history entry, every one carrying a longer
      student_answers_history than the last.
    • After the fix: the rejected submissions add no history entry at all, and student_answers_history
      holds one entry per graded attempt.

Manual: submissions that fail to grade

  1. Open a numericalresponse problem.
  2. Submit malformed input (e.g. abc) and confirm the error message is shown.
  3. Submit a valid answer.
  4. Inspect the stored state.
    • Before the fix: the malformed submission is in student_answers_history.
    • After the fix: the malformed submission is not in the list.

Regression: unchanged before and after

  • Legitimate repeated submissions still work, including multi-tab and slow connections.
  • attempts still increments exactly once per graded submission.
  • Submitting to a closed or past-due problem still behaves as before.

Deadline

None.

Other information

Back-port for older version is possible, but with a minor change on a patched function name in tests

@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Aug 24, 2026
@openedx-webhooks

Copy link
Copy Markdown

Thanks for the pull request, @shadinaif!

This repository is currently maintained by @openedx/wg-maintenance-openedx-platform-oncall.

Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review.

🔘 Get product approval

If you haven't already, check this list to see if your contribution needs to go through the product review process.

  • If it does, you'll need to submit a product proposal for your contribution, and have it reviewed by the Product Working Group.
    • This process (including the steps you'll need to take) is documented here.
  • If it doesn't, simply proceed with the next step.
🔘 Provide context

To help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:

  • Dependencies

    This PR must be merged before / after / at the same time as ...

  • Blockers

    This PR is waiting for OEP-1234 to be accepted.

  • Timeline information

    This PR must be merged by XX date because ...

  • Partner information

    This is for a course on edx.org.

  • Supporting documentation
  • Relevant Open edX discussion forum threads
🔘 Get a green build

If one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green.

🔘 Update the status of your PR

Your PR is currently marked as a draft. After completing the steps above, update its status by clicking "Ready for Review", or removing "WIP" from the title, as appropriate.


Where can I find more information?

If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources:

When can I expect my changes to be merged?

Our goal is to get community contributions seen and reviewed as efficiently as possible.

However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:

  • The size and impact of the changes that it introduces
  • The need for product review
  • Maintenance status of the parent repository

💡 As a result it may take up to several weeks or months to complete a review and merge your PR.

@github-project-automation github-project-automation Bot moved this to Needs Triage in Contributions Aug 24, 2026
@shadinaif
shadinaif force-pushed the shadinaif/fix-studentmodulehistory branch 2 times, most recently from 0410bd4 to 8875ffc Compare August 24, 2026 10:09
@shadinaif
shadinaif force-pushed the shadinaif/fix-studentmodulehistory branch from 8875ffc to 01d51e2 Compare August 24, 2026 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

open-source-contribution PR author is not from Axim or 2U

Projects

Status: Needs Triage

Development

Successfully merging this pull request may close these issues.

2 participants