jackwener/OpenCLI · error
User not found: ' + username
Error message
User not found: ' + username
What it means
The feed-by-username endpoint answered HTTP 404, meaning no Instagram account exists for the given username. The CLI translates the 404 into this explicit message. The username string is echoed verbatim into the error.
Source
Thrown at clis/instagram/unsave.js:53
throw new Error(label + ' returned malformed items payload');
}
if (idx >= feed.items.length) throw new Error('Post index ' + (idx + 1) + ' not found');
const post = feed.items[idx];
const pkRaw = post?.pk ?? post?.id;
const pk = typeof pkRaw === 'number' ? String(pkRaw) : (typeof pkRaw === 'string' ? pkRaw.trim() : '');
if (!/^\\d+$/.test(pk)) throw new Error(label + ' returned malformed post row');
const caption = typeof post?.caption?.text === 'string' ? post.caption.text.substring(0, 60) : '';
return { pk, caption };
}
function assertOkStatus(payload, label) {
if (!payload || typeof payload !== 'object' || payload.status !== 'ok') {
throw new Error(label + ' returned no success evidence');
}
}
// web_profile_info answers HTTP 400 for business accounts; feed-by-username needs no user id. See #2234.
const r1 = await fetch('https://www.instagram.com/api/v1/feed/user/' + encodeURIComponent(username) + '/username/?count=' + (idx + 1), opts);
if (!r1.ok) throw new Error(r1.status === 404 ? 'User not found: ' + username : 'HTTP ' + r1.status + ' - make sure you are logged in to Instagram');
const { pk, caption } = getPostFromFeed(await readInstagramJson(r1, 'Instagram feed-by-username'), 'Instagram feed-by-username');
const csrf = document.cookie.match(/csrftoken=([^;]+)/)?.[1] || '';
const r2 = await fetch('https://www.instagram.com/api/v1/web/save/' + pk + '/unsave/', {
method: 'POST', credentials: 'include',
headers: { ...headers, 'X-CSRFToken': csrf, 'Content-Type': 'application/x-www-form-urlencoded' },
});
if (!r2.ok) throw new Error('Failed to unsave: HTTP ' + r2.status);
assertOkStatus(await readInstagramJson(r2, 'Instagram unsave'), 'Instagram unsave');
return [{ status: 'Unsaved', user: username, post: caption || '(post #' + (idx+1) + ')' }];
})()
` },
],
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the exact current username on instagram.com and correct the argument.
- Handle renamed accounts by re-looking-up the profile.
- Skip/remove the target if the account was deleted or banned.
Example fix
// before npx cli instagram unsave --username jonh_doe --index 1 // after npx cli instagram unsave --username john_doe --index 1 # corrected spelling
Defensive patterns
Strategy: validation
Validate before calling
const exists = await profileExists(username);
if (!exists) throw new Error(`User not found: ${username}`); Try / catch
try {
await cli.unsave(user, index);
} catch (e) {
if (e.message.startsWith('User not found')) {
console.error(`Skip: ${user} does not exist (deleted, renamed, or banned).`);
} else throw e;
} Prevention
- Copy usernames exactly from instagram.com
- Handle renamed accounts via stored user IDs where possible
- Periodically validate that target accounts still exist
When it happens
Trigger: Calling unsave (or user) with a username that is misspelled, deactivated, deleted, or renamed; 404 status from /api/v1/feed/user/{username}/username/.
Common situations: Typos or wrong casing assumptions; account was deleted or banned; user changed their handle; scraping an account that blocked you (may surface differently).
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Chess.com returned 404 for ${url}
- crates.io returned 404 for ${url}.
- Flathub returned 404 for ${url}.
- hf paper
- Homebrew API returned 404 for ${url}.
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/d7e35a22774b236c.
Report an issue: GitHub.