Skip to content

ui: 'Use Partial Response' checkbox can't stay off (forced back on after reload, then stuck) #8993

Description

@donaldraph

Thanos, Prometheus and Golang version used:
Frontend bug in the Query UI (React app), not tied to a specific Go/Thanos version. Present on main (51afa7e), and unchanged since e77caa8 (v0.34.0), so every release from v0.34.0 onward is affected.

Object Storage Provider:
N/A

What happened:
There are two related bugs in how the query panel persists the "Use Partial Response" checkbox to localStorage, in pkg/ui/react-app/src/pages/graph/Panel.tsx.

  1. In componentDidMount (around line 218), the code checks whether any value is stored under the usePartialResponse localStorage key, but never actually reads what that value is:
componentDidMount(): void {
  this.executeQuery();
  const storedValue = localStorage.getItem('usePartialResponse');
  if (storedValue !== null) {
    this.setOptions({ usePartialResponse: true });
    this.props.onUsePartialResponseChange(true);
    localStorage.setItem('usePartialResponse', JSON.stringify(true));
  }
}

If anything at all is stored under that key, including the string "false", this unconditionally forces usePartialResponse to true and writes "true" back to localStorage. So the very first time a user unchecks the box (which persists "false"), the next time a Panel mounts (page reload, adding a panel, navigating back to the query page) it gets flipped back on.

  1. In handleChangePartialResponse (around line 414), once "true" has ever been persisted, the checkbox can never be unchecked again:
handleChangePartialResponse = (event: React.ChangeEvent<HTMLInputElement>): void => {
  let newValue = event.target.checked;
  const storedValue = localStorage.getItem('usePartialResponse');
  if (storedValue === 'true') {
    newValue = true;
  }
  this.setOptions({ usePartialResponse: newValue });
  this.props.onUsePartialResponseChange(newValue);
  localStorage.setItem('usePartialResponse', JSON.stringify(event.target.checked));
};

If the stored value is "true", the handler overrides whatever the user just clicked and forces newValue back to true, regardless of whether they were checking or unchecking the box.

These two compound each other in practice: bug 1 forces "true" into storage the first time the panel remounts after any value gets persisted, and once that's stored, bug 2 makes the checkbox permanently stuck on.

What you expected to happen:

  1. Unchecking "Use Partial Response" and reloading the page (or mounting a new panel) should keep it unchecked, since that's the value that was persisted.
  2. Unchecking the box should always turn it off, regardless of what was previously stored.

How to reproduce it (as minimally and precisely as possible):

  1. Open the Query UI with a clean usePartialResponse localStorage key (or clear it via devtools first).
  2. Uncheck "Use Partial Response" on a panel.
  3. Reload the page.
  4. Observe the checkbox is checked again (bug 1).
  5. Try to uncheck it.
  6. Observe it stays checked, or immediately snaps back if you inspect state right after clicking (bug 2).

Anything else we need to know:
I have an open refactor PR, #8992, that routes this same code through a shared localStorage accessor but deliberately leaves both bugs' behavior unchanged, to keep that PR a pure refactor. I'd like to submit the fix for these two bugs as a follow up PR once #8992 lands, to avoid the two PRs stepping on the same lines.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions