jackwener/OpenCLI · error · CommandExecutionError
Pinterest request failed (HTTP ${status})${detail}${hint}
Error message
Pinterest request failed (HTTP ${status})${detail}${hint} What it means
Pinterest's resource endpoint returned a non-2xx status that is not classified as auth (not 401, and not 403-on-write). The library throws CommandExecutionError including Pinterest's own error message when present and a CSRF hint for 403 responses.
Source
Thrown at clis/pinterest/utils.js:226
}
if (raw?.__httpError) {
const status = raw.__httpError;
// Reads work anonymously, so their 403 is a rejected request, not a login prompt;
// writes genuinely need login, so treat their 403 as auth too.
if (status === 401 || (WRITE_ACTIONS.has(action) && status === 403)) {
// Pinterest also answers 401 for writes it refuses on a logged-in session (e.g. editing the
// link of a scraped pin), so pass its own message through instead of only saying "log in".
throw new AuthRequiredError(
PINTEREST_DOMAIN,
raw.message
? `Pinterest refused this write: ${raw.message}`
: 'This action requires being logged in to Pinterest in Chrome',
);
}
const hint = status === 403 ? ' (missing or expired CSRF token — reload Pinterest in Chrome)' : '';
// Surface Pinterest's own error text (from resource_response.error.message) when present.
const detail = raw.message ? `: ${raw.message}` : '';
throw new CommandExecutionError(`Pinterest request failed (HTTP ${status})${detail}${hint}`);
}
if (!raw || typeof raw !== 'object' || raw.__malformed) {
throw new CommandExecutionError('Pinterest request returned malformed JSON payload');
}
const resourceResponse = raw.resource_response;
if (!resourceResponse || typeof resourceResponse !== 'object') {
throw new CommandExecutionError('Pinterest request returned malformed API payload');
}
const payload = resourceResponse.data;
const results = Array.isArray(payload)
? payload
: (payload && Array.isArray(payload.results) ? payload.results : []);
return { data: payload, results, bookmark: resourceResponse.bookmark || null };
}
/** POST a /create/ mutation; returns the created resource_response.data. */
export async function pinterestResourceCreate(page, resource, options, sourceUrl) {
const { data } = await pinterestResourceFetch(page, resource, options, sourceUrl, 'create');View on GitHub (pinned to 49907e53dc)
Solutions
- Read the detail/hint in the message — 403 means reload Pinterest in Chrome to refresh the CSRF token
- If 429, wait and back off before retrying; slow down scripted call rates
- If 404, verify the username/slug or pin exists
- Retry later for 5xx Pinterest-side errors
Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
null
Try / catch
try { const r = await cmd.userBoards(u); } catch (e) { const m = e.message.match(/HTTP (\d+)/); if (m && m[1] === '429') { await sleep(60000); return retry(); } if (m && m[1] === '403') console.error('Reload Pinterest in Chrome to refresh CSRF'); throw e; } Prevention
- Throttle scripted calls to avoid 429 rate limits
- Reload Pinterest in Chrome periodically to keep the CSRF token fresh
- Verify board/pin identifiers to avoid 404s
- Treat 5xx as transient and retry with backoff
When it happens
Trigger: HTTP 404 for a nonexistent resource (bad board/pin lookup); HTTP 403 on a read when the csrftoken is missing/expired; HTTP 429 rate limiting; HTTP 5xx from Pinterest; any other unexpected status.
Common situations: Rate limiting after rapid scripted calls (429); expired CSRF token causing 403 on reads; typos in board username/slug causing 404; Pinterest transient outages (5xx).
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
- Failed to follow: HTTP ' + r2.status
- API_ERROR
- API_ERROR
- Chess.com API returned HTTP ${resp.status} for ${url}
- Flomo API returned HTTP ${resp.status}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/0ed835e5f7f5b630.
Report an issue: GitHub.