gildas-lormeau/SingleFile · error · Error
invalid_token
invalid_token
Error message
invalid_token
What it means
getResponse converts an HTTP 401 from the Drive API into "invalid_token". This means the OAuth access token sent with the request is missing, expired, or revoked, so the API rejected the request as unauthenticated. It is the library's normalized signal that the caller must re-authenticate.
Source
Thrown at src/lib/gdrive/gdrive.js:489
}
async function getJSON(httpResponse) {
httpResponse = getResponse(httpResponse);
const response = await httpResponse.json();
if (response.error) {
throw new Error(response.error);
} else {
return response;
}
}
function getResponse(httpResponse) {
if (httpResponse.status == 200) {
return httpResponse;
} else if (httpResponse.status == 404) {
throw new Error("path_not_found");
} else if (httpResponse.status == 401) {
throw new Error("invalid_token");
} else {
throw new Error("unknown_error (" + httpResponse.status + ")");
}
}
View on GitHub (pinned to 517fb7c5cf)
Solutions
- Catch the error and re-run the auth flow (gdrive.auth) to obtain a fresh token, then retry the request once.
- Verify the stored token is still valid by checking expiry before requests; refresh proactively.
- If refresh fails, clear stored credentials and require interactive re-consent.
- Confirm the Authorization header is actually included in requests made outside the library's helpers.
Example fix
// before
const data = await gdrive.getJSON(resp); // 401 -> invalid_token
// after
try {
var data = await gdrive.getJSON(resp);
} catch (e) {
if (e.message === "invalid_token") {
await gdrive.auth(options); // refresh
data = await gdrive.getJSON(resp);
} else throw e;
} Defensive patterns
Strategy: retry
Validate before calling
function tokenLikelyValid(auth) {
return auth && typeof auth.accessToken === "string" &&
(!auth.expiry || Date.now() < auth.expiry - 60_000); // refresh 1min early
} Try / catch
try { return await callGdrive(); }
catch (e) {
if (e.message === "invalid_token") {
await gdrive.auth(options); // force re-auth/refresh
return await callGdrive(); // retry once
}
throw e;
} Prevention
- Refresh tokens proactively before the ~1h expiry
- Clear cached credentials when the user switches accounts
- Handle revocation: catch invalid_token and re-consent rather than looping
- Check host clock skew if tokens expire immediately
When it happens
Trigger: Access token expired (Google tokens last ~1 hour); user revoked the app in their Google account settings; token never attached to the request; refresh flow failed silently but a stale token is still used.
Common situations: Long-running jobs that outlive token lifetime without refreshing; users revoking access then the app retrying with cached tokens; clock skew on the host invalidating freshly issued tokens; switching accounts without clearing stored credentials.
Related errors
AI-assisted analysis of gildas-lormeau/SingleFile@517fb7c5cf (2026-09-01).
Data as JSON: /api/errors/28ab290a8b4acb1e.
Report an issue: GitHub.