sigoden/dufs · error · Error
Failed to fetch token
Error message
Failed to fetch token
What it means
This is a browser-side error thrown by setupDownloadWithToken in dufs's bundled index.js. Before following a download link, the page fetches a one-time token from the link's URL (with tokengen param); if the token request returns a non-2xx response, it throws 'Failed to fetch token' instead of navigating the download, so a stale/invalid token never reaches the actual download URL.
Solutions
- Refresh the page to re-establish session/auth state, then retry the download
- Re-login or pass correct credentials so the tokengen endpoint returns 200
- Verify the file still exists at the link's href on the server
- Check dufs --auth rules allow the current user to access the path
- Check server logs / network tab for the tokengen request's actual status code
Example fix
// before
const res = await fetch(tokengenUrl);
if (!res.ok) throw new Error("Failed to fetch token");
// after
const res = await fetch(tokengenUrl, { credentials: "same-origin" });
if (!res.ok) {
if (res.status === 401) { location.href = "/@login?next=" + encodeURIComponent(location.href); return; }
throw new Error(`Failed to fetch token: HTTP ${res.status}`);
} Defensive patterns
Strategy: try-catch
Validate before calling
const u = new URL(link.getAttribute("href"));
u.searchParams.set("tokengen", "");
if (!u) throw new Error("download link has no href"); Try / catch
try {
await setupDownloadWithToken(e);
} catch (err) {
if (String(err.message).includes("Failed to fetch token")) {
alert("Session expired — please refresh the page and log in again.");
location.reload();
} else { throw err; }
} Prevention
- Keep sessions alive; re-login before long-lived pages trigger downloads
- Use credentials: 'same-origin' on the token fetch
- Verify auth rules permit the target path
- Check the file still exists before offering the link
When it happens
Trigger: User clicks a download link whose href points at a resource requiring auth, but the tokengen fetch (fetch(tokengenUrl)) responds with res.ok === false — e.g. 401 because the session/token cookies expired, 403 because the user lost write permission, or 404 because the target file was deleted or moved before the click.
Common situations: Session expired while the index page stayed open; server restarted and in-memory auth state changed; the file was renamed/removed between page render and click; a proxy stripped the tokengen query param; misconfigured auth rules (--auth) denying the user access to that path.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
AI-assisted analysis of sigoden/dufs@fe7fd564f8 (2026-09-09).
Data as JSON: /api/errors/f2dc5a4308552097.
Report an issue: GitHub.
Appendix: source
Thrown at assets/index.js:567
try {
await checkAuth("login");
} catch { }
location.reload();
});
}
}
function setupDownloadWithToken() {
document.querySelectorAll("a.dlwt").forEach(link => {
link.addEventListener("click", async e => {
e.preventDefault();
try {
const link = e.currentTarget || e.target;
const originalHref = link.getAttribute("href");
const tokengenUrl = new URL(originalHref);
tokengenUrl.searchParams.set("tokengen", "");
const res = await fetch(tokengenUrl);
if (!res.ok) throw new Error("Failed to fetch token");
const token = await res.text();
const downloadUrl = new URL(originalHref);
downloadUrl.searchParams.set("token", token);
const tempA = document.createElement("a");
tempA.href = downloadUrl.toString();
tempA.download = "";
document.body.appendChild(tempA);
tempA.click();
document.body.removeChild(tempA);
} catch (err) {
alert(`Failed to download, ${err.message}`);
}
});
});
}
function setupSearch() {
const $searchbar = document.querySelector(".searchbar");View on GitHub (pinned to fe7fd564f8)