Skip to content

fix: add safe enterprise context defaults to survive stale Mako cache after PR #38094#38642

Draft
Copilot wants to merge 2 commits into
masterfrom
copilot/investigate-mako-cache-issue
Draft

fix: add safe enterprise context defaults to survive stale Mako cache after PR #38094#38642
Copilot wants to merge 2 commits into
masterfrom
copilot/investigate-mako-cache-issue

Conversation

Copy link
Copy Markdown

Copilot AI commented May 14, 2026

Description

PR #38094 removed consent_required_courses and other enterprise variables from student_dashboard() context, relying on DashboardContextEnricher (via DashboardRenderStarted filter) to supply them. Deployments with a stale compiled Mako cache at /tmp/mako_lms/…/dashboard.html.py still contain the pre-#38094 line:

show_consent_link = (session_id in consent_required_courses)

When consent_required_courses is absent from context, Mako resolves it to Undefined. The in membership test on Undefined raises TypeError: argument of type 'Undefined' is not iterable, crashing the dashboard for all users until the cache is regenerated.

Changes:

  • student/views/dashboard.py — adds safe defaults to the context dict before the filter runs, so stale-cache code paths don't crash and non-enterprise deployments degrade gracefully:

    'enterprise_message': '',
    'consent_required_courses': set(),          # stale-cache guard
    'enterprise_learner_portal_enabled_message': None,
    'banner_account_activation_message': None,

    DashboardContextEnricher will overwrite these with real values when the enterprise package is active.

  • lms/envs/common.py — changes fail_silently: Falsefail_silently: True for the DashboardContextEnricher pipeline entry, matching the pattern already used by AccountSettingsReadOnlyFieldsStep. With fail_silently: False any exception inside the enricher propagates uncaught and crashes the entire dashboard render.

Supporting information

Testing instructions

  1. Simulate a stale cache by manually adding show_consent_link = (session_id in consent_required_courses) inside the % for loop of dashboard.html (or reproduce by not clearing /tmp/mako_lms/ after deploying feat: remove enterprise dashboard context imports (ENT-11569) #38094).
  2. Load the learner dashboard as an enrolled user — previously this raised TypeError; with this fix it renders correctly (show_consent_link evaluates False).
  3. Verify the dashboard still renders correctly on a clean cache (no stale artifact).
  4. Verify enterprise dashboard banners still appear when the enterprise package and DashboardContextEnricher are active (the filter overwrites the empty defaults).

Deadline

Urgent — active production 500s on the learner dashboard.

Other information

The root fix for the crash is providing consent_required_courses = set() in context. The fail_silently change is a correctness/consistency fix: the dashboard filter should not be able to kill the dashboard render on its own.

Original prompt

The user believes a production dashboard error after merging PR #38094 may be caused by a stale compiled Mako cache rather than current source code. Investigate where the compiled line show_consent_link = (session_id in consent_required_courses) originated from in openedx/openedx-platform on master, identify the source template/code that would have generated that compiled Mako line, and explain whether the issue is likely stale compiled templates versus a current source mismatch. Focus on locating the originating source in the repository history/current code and provide the minimal explanation needed for the user.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: I merged in this PR but am now seeing issues in DataDog as follows. What was incorrect about this PR, and what is needed to fix it?

Here is the information given to me from the DataDog AI
Root Cause in the Stack Trace
The crash happens in the Mako template dashboard.html.py at line 243:

show_consent_link = (session_id in consent_required_courses)

The variable consent_required_courses is Mako Undefined (not passed into the template context), so Python can't perform an in membership test on it — hence argument of type 'Undefined' is not iterable.

The call chain (confirming your coworker's description):

openedx/core/djangoapps/util/maintenance_banner.py line 42 (decorator _decorated)
→ common/djangoapps/student/views/dashboard.py line 889 (student_dashboard → render_to_response)
→ Mako template lms/templates/dashboard.html renders and hits the Undefined variable

What to Fix
The consent_required_courses context variable needs to be defined before it reaches the template. In student_dashboard() in dashboard.py, ensure consent_required_courses is included in the template context dict (likely it was removed or renamed in your recent deploy). A quick defensive fix in the template would be:

show_consent_link = (session_id in consent_required_courses) if consent_required_courses is not UNDEFINED else False

But the proper fix is to ensure the view passes consent_required_courses in the context.

Assistant: The PR was incomplete: it removed the view-side context population for enterprise dashboard data, but it did not fully remove all template references to that data. The production error is the result of that mismatch.

What was incorrect in the PR

In common/djangoapps/student/views/dashboard.py, the PR removed these imports and context values:

  • get_dashboard_consent_notification
  • get_enterprise_learner_portal_context
  • is_enterprise_learner
  • enterprise_message
  • consent_required_courses

and also deleted the old helper get_consent_required_courses from openedx/features/enterprise_support/api.py. That means the dashboard view no longer provides enterprise consent/dashboard context at all.

At the same time, the PR only partially updated the dashboard templates:

  • It did remove show_consent_link = (session_id in consent_required_courses) from lms/templates/dashboard.html.
  • It did remove show_consent_link from the include args passed to _dashboard_course_listing.html.
  • It did remove the consent include block from _dashboard_course_listing.html.
  • It deleted _dashboard_show_consent.html.

Those removals are consistent with deleting the old consent UI.

However, the current master version of lms/templates/dashboard.html still contains a top-level block:

% if enterprise_message:
    <div class="dashboard-banner">
        ${ enterprise_message | n, decode.utf8 }
    </div>
% endif

while the PR explicitly removed enterprise_message from the dashboard view context. So the template still expects enterprise data that the view no longer passes. In Mako, an omitted variable becomes Undefined, and using it in control flow can crash rendering rather than simply evaluate false. That is the underlying class of bug introduced by this PR. The same mismatch can explain the Datadog error you were given about consent_required_courses: a template path still referenced a variable after the view stopped providing it. PR data: merged May 12, 2026; 7 files changed; dashboard.py lost both enterprise_message and consent_required_courses from context. citeturn0commentaryto=functions.get-github-data1turn0commentaryto=functions.get-github-data2turn0commentaryto=functions.get-github-data3

The concrete mistake

The mistake was assuming the event-pipeline replacement fully covered the old template contract. The PR added a new event pipeline entry:

"org.openedx.learning.dashboard.render.started.v1": {
    "fail_silently": False,
    "pipeline": ["enterprise.filters.dashboard.DashboardContextEnricher"],
},

but it also removed the legacy context variables directly from student_dashboard(). If that new enrichment path does not always inject every variable the templates still reference, the dashboar...

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Investigate stale Mako compiled cache for dashboard error fix: add safe enterprise context defaults to survive stale Mako cache after PR #38094 May 14, 2026
Copilot AI requested a review from kiram15 May 14, 2026 02:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants