go-gitea/gitea · warning
Failed to reload page: ${resp.statusText}
Error message
Failed to reload page: ${resp.statusText} What it means
Thrown by the issue sidebar combo-list component after the user changes a sidebar value (labels, milestone, assignees, etc.). To reflect the change it re-fetches the current page with GET(window.location.href) and re-parses it; any non-2xx response aborts the partial refresh so the sidebar would otherwise show stale data.
Source
Thrown at web_src/js/features/repo-issue-sidebar-combolist.ts:88
updateUiList(changedValues: Array<string>) {
if (!this.elList) return;
const elEmptyTip = this.elList.querySelector(':scope > .item.empty-list')!;
queryElemChildren(this.elList, '.item:not(.empty-list)', (el) => el.remove());
for (const value of changedValues) {
const el = this.elDropdown.querySelector<HTMLElement>(`.menu > .item[data-value="${CSS.escape(value)}"]`);
if (!el) continue;
const listItem = el.cloneNode(true) as HTMLElement;
queryElems(listItem, '.item-check-mark, .item-secondary-info', (el) => el.remove());
this.elList.append(listItem);
}
const hasItems = Boolean(this.elList.querySelector('.item:not(.empty-list)'));
toggleElem(elEmptyTip, !hasItems);
}
async reloadPagePartially() {
const resp = await GET(window.location.href);
if (!resp.ok) throw new Error(`Failed to reload page: ${resp.statusText}`);
const doc = parseDom(await resp.text(), 'text/html');
// we can safely replace the whole right part (sidebar) because there are only some dropdowns and lists
const newSidebar = doc.querySelector('.issue-content-right')!;
this.elIssueSidebar.replaceWith(newSidebar);
// for the main content (left side), at the moment we only support handling known timeline items
const newMainContent = doc.querySelector('.issue-content-left')!;
syncIssueMainContentTimelineItems(this.elIssueMainContent, newMainContent);
}
async sendRequestToBackend(changedValues: Array<string>): Promise<Response | null> {
let lastResp: Response | null = null;
if (this.updateAlgo === 'diff') {
for (const value of this.initialValues) {
if (!changedValues.includes(value)) {
lastResp = await POST(this.updateUrl, {data: new URLSearchParams({action: 'detach', id: value})});
if (!lastResp.ok) return lastResp;View on GitHub (pinned to 43ace7cc8a)
Solutions
- Reload the full page (F5) — this re-authenticates and rebuilds the sidebar; the sidebar change itself usually already applied via sendRequestToBackend
- Log in again if the session expired, then retry the sidebar action
- Verify the issue URL still resolves (repo not renamed/transfered/private)
- If 500/502, check server and proxy logs for the failing page render
Example fix
// before
const resp = await GET(window.location.href);
if (!resp.ok) throw new Error(`Failed to reload page: ${resp.statusText}`);
// after (fall back to a full page reload instead of just erroring)
const resp = await GET(window.location.href);
if (!resp.ok) {
if (resp.redirected || resp.status === 401 || resp.status === 403) window.location.reload();
else throw new Error(`Failed to reload page: ${resp.status} ${resp.statusText}`);
} Defensive patterns
Strategy: fallback
Validate before calling
// Verify the page is still reachable and the response is the same document before swapping
const resp = await GET(window.location.href, {headers: {'X-No-Redirect': '1'}});
if (!resp.ok || resp.redirected) throw new Error(`Failed to reload page: ${resp.status}`); Type guard
const isIssueDocument = (doc: Document): boolean =>
!!doc.querySelector('.issue-content-right') && !!doc.querySelector('.issue-content-left'); Try / catch
try {
await comboList.reloadPagePartially();
} catch {
// fallback: the sidebar request already succeeded; a full reload re-syncs the UI
window.location.reload();
} Prevention
- Treat the partial reload as best-effort: the underlying value change already applied, so falling back to a full page reload is always safe
- Detect auth loss early (401/403/redirected responses) and redirect to login instead of showing a toast
- Keep sessions alive or prompt re-login before long-lived sidebar interactions
When it happens
Trigger: GET of the current issue URL returns non-ok: session expired and the anonymous request got a redirect-to-login that fails resp.ok handling or a 403 for a private repo, the issue was deleted or the repo made private/transfered while open (404), or the server/proxy errored (500/502).
Common situations: Long-lived tab whose session cookie expired before a sidebar edit was saved; issue moved by migration or repo transfer; SSO/proxy in front of Gitea rejecting the re-fetch; server restart mid-session.
Related errors
- Invalid server response: ${response.status}
- Failed to update issue title: ${resp.statusText}
- Failed to update PR target branch: ${resp.statusText}
- Unable to render the PDF file
AI-assisted analysis of go-gitea/gitea@43ace7cc8a (2026-08-15).
Data as JSON: /api/errors/b95ce7257c610260.
Report an issue: GitHub.