sahat/hackathon-starter · error · Error
HTTP error! status: ${response.status}
Error message
HTTP error! status: ${response.status} What it means
After a successful Tumblr OAuth 1.0a login, the strategy fetches https://api.tumblr.com/v2/user/info with a signed header and throws on any non-2xx HTTP status.
Source
Thrown at config/passport.js:605
state: true,
passReqToCallback: true,
},
async (req, token, tokenSecret, profile, done) => {
try {
if (!token || !tokenSecret) {
throw new Error('Missing or invalid token/tokenSecret');
}
// Helper function to generate the OAuth 1.0a authHeader for Tumblr API.
// This function is not going to make any actual calls to
// tumblr's /request_token or /access_token endpoints.
function getTumblrAuthHeader(url, method) {
const oauth = new OAuth('https://www.tumblr.com/oauth/request_token', 'https://www.tumblr.com/oauth/access_token', process.env.TUMBLR_KEY, process.env.TUMBLR_SECRET, '1.0A', null, 'HMAC-SHA1');
return oauth.authHeader(url, token, tokenSecret, method);
}
const userInfoURL = 'https://api.tumblr.com/v2/user/info';
const response = await fetch(userInfoURL, { headers: { Authorization: getTumblrAuthHeader(userInfoURL, 'GET') } });
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
// Extract user info from the API response
const tumblrUser = data.response.user;
const primaryBlog = tumblrUser.blogs?.find((blog) => blog.primary) || tumblrUser.blogs?.[0];
const providerProfile = {
id: primaryBlog.uuid || tumblrUser.name,
name: tumblrUser.name,
picture: primaryBlog?.avatar?.[0]?.url,
website: primaryBlog?.url,
};
try {
const sessionAlreadyLoggedIn = !!req.user;
const user = await handleAuthLogin(req, token, null, 'tumblr', {}, providerProfile, sessionAlreadyLoggedIn, tokenSecret, false);
if (sessionAlreadyLoggedIn && req.user.id === user.id) {
req.flash('info', { msg: 'Tumblr account has been linked.' });
}
return done(null, user);View on GitHub (pinned to c12e339564)
Solutions
- Check response.status in server logs: 401 → re-authorize the app (unlink/relink); 429 → back off and retry
- Verify system clock is accurate (OAuth 1.0a timestamps are sensitive)
- Confirm TUMBLR_KEY/TUMBLR_SECRET in .env still match the registered Tumblr app
Example fix
// before
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
// after
if (!response.ok) return done(null, false, { msg: `Tumblr API returned ${response.status}. Try relinking your account.` }); Defensive patterns
Strategy: retry
Try / catch
catch (e) { if (/HTTP error! status: (401|429)/.test(e.message)) { /* re-auth or backoff */ } throw e; } Prevention
- Keep server clocks NTP-synced for OAuth 1.0a signing
- Handle non-OK as done(null,false) with a flash message instead of a hard throw
When it happens
Trigger: Tumblr's user/info endpoint returns 401 (bad signature/expired token), 429 (rate limit), or 5xx during the verify callback of the Tumblr strategy.
Common situations: System clock skew breaking the HMAC-SHA1 signed header, revoked or expired access token, TUMBLR_KEY changed since the token was issued, or Tumblr API downtime/rate limiting.
Related errors
AI-assisted analysis of sahat/hackathon-starter@c12e339564 (2026-08-27).
Data as JSON: /api/errors/c540fbcab3478889.
Report an issue: GitHub.