tinyhumansai/openhuman · error · Error

No screenshots found in ${screenshotDir}

Error message

No screenshots found in ${screenshotDir}

What it means

uploadScreenshots() globs fastlane/screenshots/en-US for files ending exactly in '.png' (case-sensitive), sorts them, and refuses to run when the list is empty. This check deliberately runs BEFORE deleteExistingScreenshotSet(), so an empty directory fails safely instead of wiping the live screenshot set and uploading nothing.

Source

Thrown at scripts/ios-appstore-metadata.mjs:303

    data: {
      type: "appScreenshots",
      id: reservation.data.id,
      attributes: {
        uploaded: true,
        sourceFileChecksum: checksum,
      },
    },
  });
  console.log(`[ios-appstore-metadata] uploaded ${fileName}`);
}

async function uploadScreenshots(localization) {
  const files = (await readdir(screenshotDir))
    .filter((file) => file.endsWith(".png"))
    .sort()
    .map((file) => path.join(screenshotDir, file));
  if (!files.length) {
    throw new Error(`No screenshots found in ${screenshotDir}`);
  }

  await deleteExistingScreenshotSet(localization);
  const set = await createScreenshotSet(localization);
  for (const file of files) {
    await uploadScreenshot(set, file);
  }
}

await updateAppInfoLocalization();
const versionLocalization = await updateVersionLocalization();
await uploadScreenshots(versionLocalization);

console.log(
  "[ios-appstore-metadata] metadata and screenshots submitted to App Store Connect.",
);

View on GitHub (pinned to a221052e0d)

Solutions

  1. Capture or copy the PNGs into <repo>/fastlane/screenshots/en-US before running
  2. Rename files to lowercase .png (e.g. `for f in *.PNG; do mv "$f" "${f%.PNG}.png"; done`)
  3. Re-run `node scripts/ios-appstore-metadata.mjs`; existing remote screenshots are only deleted once local files are confirmed present

Example fix

# before
ls fastlane/screenshots/en-US   # empty → script aborts

# after
mkdir -p fastlane/screenshots/en-US
cp ~/captures/*.png fastlane/screenshots/en-US/
node scripts/ios-appstore-metadata.mjs
Defensive patterns

Strategy: validation

Validate before calling

import { readdir } from 'node:fs/promises';
const pngs = (await readdir('fastlane/screenshots/en-US')).filter(f => f.endsWith('.png'));
if (pngs.length === 0) {
  console.error('No lowercase-.png screenshots in fastlane/screenshots/en-US — capture them first');
  process.exit(1);
}

Prevention

When it happens

Trigger: Fresh clone where screenshots were never captured; screenshots exist under a different locale directory (the path is hardcoded to fastlane/screenshots/en-US and does NOT follow ASC_LOCALE); files named .PNG/.jpg (endsWith('.png') is case-sensitive); wrong working directory assumptions.

Common situations: Running the metadata script before the screenshot-capture step on a new machine; a capture tool writing `01_home.PNG` uppercase extensions; screenshots landing in fastlane/screenshots/de-DE while the script only reads en-US.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/709993206fe4693f. Report an issue: GitHub.