jackwener/OpenCLI · error · EmptyResultError

pin "${id}" not found

Error message

pin "${id}" not found

What it means

The download command fetched the pin via PinResource (field_set_key 'detailed') and got either no pin object or one without an id, meaning the pin id/URL does not resolve. It raises EmptyResultError before attempting any image download.

Source

Thrown at clis/pinterest/download.js:36

    { name: 'pin', type: 'string', positional: true, required: true, help: 'Pin id or pin URL, e.g. 1234567890123456' },
    { name: 'output', type: 'string', default: './pinterest-downloads', help: 'Output directory' },
  ],
  columns: ['pinId', 'status', 'size', 'path'],
  func: async (page, kwargs) => {
    const id = parsePinId(kwargs.pin);
    const output = String(kwargs.output ?? './pinterest-downloads');

    const sourceUrl = `/pin/${id}/`;
    await page.goto(`${PINTEREST_BASE}${sourceUrl}`);

    const { data: pin } = await pinterestResourceFetch(
      page,
      'PinResource',
      { id, field_set_key: 'detailed' },
      sourceUrl,
    );
    if (!pin || !pin.id) {
      throw new EmptyResultError('pinterest download', `pin "${id}" not found`);
    }
    const imageUrl = pickPinImage(pin.images);
    if (!imageUrl) {
      throw new CommandExecutionError(`Pin ${id} has no downloadable image (it may be a video or story pin)`);
    }

    fs.mkdirSync(output, { recursive: true });
    const ext = path.extname(new URL(imageUrl).pathname) || '.jpg';
    const destPath = path.join(output, `${id}${ext}`);

    let result;
    try {
      result = await httpDownload(imageUrl, destPath, { timeout: 60000 });
    } catch (err) {
      throw new CommandExecutionError(`Failed to download pin ${id}: ${getErrorMessage(err)}`);
    }
    if (!result.success) {
      throw new CommandExecutionError(`Failed to download pin ${id}: ${result.error || 'unknown error'}`);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open the pin URL in a browser to confirm it still exists.
  2. Re-check the pin id argument for typos or truncation.
  3. Catch EmptyResultError and mark the pin as unavailable in your batch job.
  4. Try the full pin URL instead of a bare id (or vice versa) so resolution uses the intended source.

Example fix

// before
await cli.download('9999999999'); // deleted pin
// after
try { await cli.download(pinUrl); } catch (e) { console.warn('pin unavailable', pinUrl); }
Defensive patterns

Strategy: try-catch

Validate before calling

if (!idOrUrl || String(idOrUrl).trim().length < 5) throw new Error('provide a valid pin id or URL');
// optionally probe:
const res = await fetch(pinUrl, { method: 'HEAD' });
if (!res.ok) console.warn('pin may be gone:', pinUrl);

Type guard

function looksLikePinId(v) {
  return /^\d{6,}$/.test(String(v).trim());
}

Try / catch

try {
  await cli.download(pinId);
} catch (e) {
  if (/not found/.test(e.message)) {
    unavailable.push(pinId); // record and continue batch
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `pinterest download <pinIdOrUrl>` with a deleted pin, a mistyped id, a malformed URL that still yields an id-like string, or a pin that is private/moderated and invisible to the session.

Common situations: Dead links in scraped datasets; pins removed by the pinner or Pinterest moderation; region-blocked content; copying an id from a redirect that no longer exists.

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/e7ee7e3f27ac4fa4. Report an issue: GitHub.