{"record":{"id":"b95ce7257c610260","repo":"go-gitea/gitea","slug":"failed-to-reload-page-resp-statustext","errorCode":null,"errorMessage":"Failed to reload page: ${resp.statusText}","messagePattern":"Failed to reload page: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"web_src/js/features/repo-issue-sidebar-combolist.ts","lineNumber":88,"sourceCode":"\n  updateUiList(changedValues: Array<string>) {\n    if (!this.elList) return;\n    const elEmptyTip = this.elList.querySelector(':scope > .item.empty-list')!;\n    queryElemChildren(this.elList, '.item:not(.empty-list)', (el) => el.remove());\n    for (const value of changedValues) {\n      const el = this.elDropdown.querySelector<HTMLElement>(`.menu > .item[data-value=\"${CSS.escape(value)}\"]`);\n      if (!el) continue;\n      const listItem = el.cloneNode(true) as HTMLElement;\n      queryElems(listItem, '.item-check-mark, .item-secondary-info', (el) => el.remove());\n      this.elList.append(listItem);\n    }\n    const hasItems = Boolean(this.elList.querySelector('.item:not(.empty-list)'));\n    toggleElem(elEmptyTip, !hasItems);\n  }\n\n  async reloadPagePartially() {\n    const resp = await GET(window.location.href);\n    if (!resp.ok) throw new Error(`Failed to reload page: ${resp.statusText}`);\n    const doc = parseDom(await resp.text(), 'text/html');\n\n    // we can safely replace the whole right part (sidebar) because there are only some dropdowns and lists\n    const newSidebar = doc.querySelector('.issue-content-right')!;\n    this.elIssueSidebar.replaceWith(newSidebar);\n\n    // for the main content (left side), at the moment we only support handling known timeline items\n    const newMainContent = doc.querySelector('.issue-content-left')!;\n    syncIssueMainContentTimelineItems(this.elIssueMainContent, newMainContent);\n  }\n\n  async sendRequestToBackend(changedValues: Array<string>): Promise<Response | null> {\n    let lastResp: Response | null = null;\n    if (this.updateAlgo === 'diff') {\n      for (const value of this.initialValues) {\n        if (!changedValues.includes(value)) {\n          lastResp = await POST(this.updateUrl, {data: new URLSearchParams({action: 'detach', id: value})});\n          if (!lastResp.ok) return lastResp;","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/go-gitea/gitea/blob/43ace7cc8ad5fa20027b1ca5b3ab5f1134972ed5/web_src/js/features/repo-issue-sidebar-combolist.ts#L70-L106","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nconst resp = await GET(window.location.href);\nif (!resp.ok) throw new Error(`Failed to reload page: ${resp.statusText}`);\n\n// after (fall back to a full page reload instead of just erroring)\nconst resp = await GET(window.location.href);\nif (!resp.ok) {\n  if (resp.redirected || resp.status === 401 || resp.status === 403) window.location.reload();\n  else throw new Error(`Failed to reload page: ${resp.status} ${resp.statusText}`);\n}","handlingStrategy":"fallback","validationCode":"// Verify the page is still reachable and the response is the same document before swapping\nconst resp = await GET(window.location.href, {headers: {'X-No-Redirect': '1'}});\nif (!resp.ok || resp.redirected) throw new Error(`Failed to reload page: ${resp.status}`);","typeGuard":"const isIssueDocument = (doc: Document): boolean =>\n  !!doc.querySelector('.issue-content-right') && !!doc.querySelector('.issue-content-left');","tryCatchPattern":"try {\n  await comboList.reloadPagePartially();\n} catch {\n  // fallback: the sidebar request already succeeded; a full reload re-syncs the UI\n  window.location.reload();\n}","preventionTips":["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"],"tags":["network","http","session","sidebar","gitea-frontend"],"backgroundTag":null,"analyzedSha":"43ace7cc8ad5fa20027b1ca5b3ab5f1134972ed5","analyzedAt":"2026-08-15T09:36:00.065Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}