{"record":{"id":"2afb090be8e7b35a","repo":"seaweedfs/seaweedfs","slug":"failed-to-fetch-group","errorCode":null,"errorMessage":"Failed to fetch group","messagePattern":"Failed to fetch group","errorType":"console","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"weed/admin/view/app/groups.templ","lineNumber":272,"sourceCode":"                    const error = await response.json().catch(() => ({}));\n                    showAlert('Failed to create group: ' + (error.error || 'Unknown error'), 'error');\n                }\n            } catch (error) {\n                showAlert('Failed to create group: ' + error.message, 'error');\n            }\n        }\n\n        async function viewGroup(name) {\n            currentGroupName = name;\n            document.getElementById('viewGroupTitle').textContent = 'Group: ' + name;\n            await refreshGroupDetails(name);\n            new bootstrap.Modal(document.getElementById('viewGroupModal')).show();\n        }\n\n        async function refreshGroupDetails(requestedName) {\n            try {\n                const response = await fetch(basePath('/api/groups/' + encodeURIComponent(requestedName)));\n                if (!response.ok) throw new Error('Failed to fetch group');\n                if (requestedName !== currentGroupName) return; // stale response\n                const group = await response.json();\n\n                // Render members using DOM APIs to prevent XSS\n                const membersList = document.getElementById('membersList');\n                membersList.innerHTML = '';\n                const membersTable = document.createElement('table');\n                membersTable.className = 'table table-sm';\n                const membersTbody = document.createElement('tbody');\n                if (group.members && group.members.length > 0) {\n                    for (const member of group.members) {\n                        const tr = membersTbody.insertRow();\n                        const td1 = tr.insertCell();\n                        td1.textContent = member;\n                        const td2 = tr.insertCell();\n                        const btn = document.createElement('button');\n                        btn.className = 'btn btn-sm btn-outline-danger';\n                        btn.onclick = () => removeMember(member);","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/seaweedfs/seaweedfs/blob/1c926e8fac8e8001ce25efa1027c90b02b4a1804/weed/admin/view/app/groups.templ#L254-L290","documentation":"In the SeaweedFS admin UI (weed/admin/view/app/groups.templ), refreshGroupDetails fetches GET {basePath}/api/groups/{name} and throws Error('Failed to fetch group') on any non-2xx response (groups.templ:271-272). The function's catch only logs to console.error (groups.templ:332-334), so the View Group modal still opens but renders stale or empty member/policy tables.","triggerScenarios":"Clicking View on a group that was deleted after the groups table was rendered (404); expired admin session (401/403); server error (500); basePath mismatch when the UI is mounted under a reverse-proxy prefix so /api/groups/... 404s.","commonSituations":"Two admins editing groups concurrently; leaving the admin page open past session expiry; serving the admin UI behind a proxy that strips or rewrites the /api prefix.","solutions":["Reload the groups page and retry — the group most likely no longer exists","Open browser devtools Network tab and check the actual status: 401/403 → re-authenticate; 500 → inspect weed server logs; 404 → deleted group or wrong path","Verify basePath/reverse-proxy config so the UI requests the correct /api/... URL","Improve the handler: include response.status/response.statusText in the error and surface it in the modal instead of only console.error"],"exampleFix":"// before\nif (!response.ok) throw new Error('Failed to fetch group');\n// ... catch (error) { console.error('Error fetching group details:', error); }\n\n// after\nif (!response.ok) throw new Error('Failed to fetch group: ' + response.status + ' ' + response.statusText);\n// ... catch (error) {\n    console.error('Error fetching group details:', error);\n    document.getElementById('membersList').innerHTML = '<div class=\"alert alert-danger\">' + error.message + '</div>';\n}","handlingStrategy":"try-catch","validationCode":"async function groupExists(name) {\n    const r = await fetch(basePath('/api/groups/' + encodeURIComponent(name)));\n    return r.ok; // 200 → safe to open the View modal\n}","typeGuard":null,"tryCatchPattern":"try {\n    const response = await fetch(basePath('/api/groups/' + encodeURIComponent(name)));\n    if (!response.ok) throw new Error('Failed to fetch group: ' + response.status);\n    // render\n} catch (error) {\n    showErrorInModal(error.message); // surface in the modal, not only console\n}","preventionTips":["Include response.status in thrown errors so 401/500 are distinguishable from 404","Reload the groups list when a view fetch fails — stale tables are the usual cause","Keep admin sessions short-lived and re-fetch before mutating/detail views"],"tags":["admin-ui","fetch","groups","api","javascript"],"backgroundTag":null,"analyzedSha":"1c926e8fac8e8001ce25efa1027c90b02b4a1804","analyzedAt":"2026-08-15T15:37:02.018Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}