---
title: The missing flag that lost every portal learner’s progress
description: An Odoo controller worked for staff and returned an error for every portal user. The cause was one missing argument, and the tests could not see it.
image: https://orbitalobjectives.com/hubfs/oo-social-share.png
---

[Skip to content](https://orbitalobjectives.com/insights/the-missing-flag-that-lost-every-portal-learners-progress#main)

[rbital bjectives](https://orbitalobjectives.com/)

- [Services](https://orbitalobjectives.com/services)
- [Our Work](https://orbitalobjectives.com/work)
- [About](https://orbitalobjectives.com/about)
- [Insights](https://orbitalobjectives.com/insights)

[Discuss Your Project](https://orbitalobjectives.com/contact)

1. [Insights](https://orbitalobjectives.com/insights)
2. Nov 12, 2026, 9:42:58 AM

# The missing flag that lost every portal learner’s progress

An Odoo controller worked for staff and returned an error for every portal user. The cause was one missing argument, and the tests could not see it.

By Orbital Objectives

Customers reported that their course progress never saved. Staff could not reproduce it. Every internal test passed.

## Root cause

The controller route that receives progress updates used website features but was declared without website=True. For internal users the request happened to work. For portal users the website context was missing, the handler raised, and the endpoint returned a server error. The course player ignored the failed save and carried on.

## Why the tests missed it

The existing test called the route as a public user. That path returned early, before the line that failed, so the test passed without ever exercising the code a real learner hits.

## The fix

- Declare the route with website=True.
- Add a regression test that signs in as a portal user and asserts the progress is stored.
- Check any other custom or third-party route used by portal users for the same omission. I found the identical bug in a vendored module’s consent page.

The wider lesson is about test users. Internal, portal and public users take different paths through the same controller. A test suite that covers only one of them is covering a third of the code.

[All articles →](https://orbitalobjectives.com/insights)

Next step

## Tell me what is stuck.

A first conversation is 30 minutes with the person who would do the work. You will leave knowing whether I am the right fit and roughly what it would take.

[Discuss Your Project →](https://orbitalobjectives.com/contact)[Explore Our Work](https://orbitalobjectives.com/work)

[rbital bjectives](https://orbitalobjectives.com/)

Everything orbits your objective

Independent Salesforce, HubSpot and Odoo consulting. Massachusetts.

#### Services

- [Consulting & Development](https://orbitalobjectives.com/services#salesforce-consulting-development)
- [CPQ & Revenue Operations](https://orbitalobjectives.com/services#salesforce-cpq-revenue-operations)
- [Service Cloud & Automation](https://orbitalobjectives.com/services#service-cloud-automation)
- [Experience Cloud & Partner Portals](https://orbitalobjectives.com/services#experience-cloud-partner-portals)
- [Integrations & Data Migration](https://orbitalobjectives.com/services#salesforce-integrations-data-migration)
- [All services](https://orbitalobjectives.com/services)

#### Practice

- [Our Work](https://orbitalobjectives.com/work)
- [About](https://orbitalobjectives.com/about)
- [Insights](https://orbitalobjectives.com/insights)
- [Contact](https://orbitalobjectives.com/contact)

#### Contact

- [info@orbitalobjectives.com](mailto:info@orbitalobjectives.com)
- [Discuss Your Project](https://orbitalobjectives.com/contact)

© 2026 Orbital Objectives LLCSalesforce and Odoo are trademarks of their respective owners.

```json
{
  "@context" : "https://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@id" : "https://orbitalobjectives.com/#organization"
  },
  "dateModified" : "2026-11-12",
  "datePublished" : "2026-11-12",
  "description" : "An Odoo controller worked for staff and returned an error for every portal user. The cause was one missing argument, and the tests could not see it.",
  "headline" : "<span id=\"hs_cos_wrapper_name\" class=\"hs_cos_wrapper hs_cos_wrapper_meta_field hs_cos_wrapper_type_text\" style=\"\" data-hs-cos-general-type=\"meta_field\" data-hs-cos-type=\"text\" >The missing flag that lost every portal learner’s progress</span>",
  "publisher" : {
    "@id" : "https://orbitalobjectives.com/#organization"
  },
  "url" : "https://orbitalobjectives.com/insights/the-missing-flag-that-lost-every-portal-learners-progress"
}
```

```json
{
  "@context" : "https://schema.org",
  "@type" : "BreadcrumbList",
  "itemListElement" : [ {
    "@type" : "ListItem",
    "item" : "https://orbitalobjectives.com/",
    "name" : "Home",
    "position" : 1
  }, {
    "@type" : "ListItem",
    "item" : "https://orbitalobjectives.com/insights",
    "name" : "Insights",
    "position" : 2
  }, {
    "@type" : "ListItem",
    "item" : "https://orbitalobjectives.com/insights/the-missing-flag-that-lost-every-portal-learners-progress",
    "name" : "<span id=\"hs_cos_wrapper_name\" class=\"hs_cos_wrapper hs_cos_wrapper_meta_field hs_cos_wrapper_type_text\" style=\"\" data-hs-cos-general-type=\"meta_field\" data-hs-cos-type=\"text\" >The missing flag that lost every portal learner’s progress</span>",
    "position" : 3
  } ]
}
```