{"record":{"id":"d6b92cb773e48f9d","repo":"tinyhumansai/openhuman","slug":"no-appinfos-found-for-app-appid","errorCode":null,"errorMessage":"No appInfos found for app ${appId}.","messagePattern":"No appInfos found for app (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/ios-appstore-metadata.mjs","lineNumber":118,"sourceCode":"    throw new Error(\n      `asset upload failed: ${res.status} ${res.statusText} ${await res.text()}`,\n    );\n  }\n}\n\nasync function textFile(name) {\n  return (await readFile(path.join(metadataDir, name), \"utf8\")).trim();\n}\n\nasync function firstPage(resourcePath) {\n  const payload = await request(\"GET\", resourcePath);\n  return payload.data || [];\n}\n\nasync function getOrCreateAppInfoLocalization() {\n  const appInfos = await firstPage(`/apps/${appId}/appInfos?limit=10`);\n  if (!appInfos.length) {\n    throw new Error(`No appInfos found for app ${appId}.`);\n  }\n  const appInfo = appInfos[0];\n  const existing = await firstPage(\n    `/appInfos/${appInfo.id}/appInfoLocalizations?limit=50`,\n  );\n  const match = existing.find((item) => item.attributes?.locale === locale);\n  if (match) return match;\n\n  const created = await request(\"POST\", \"/appInfoLocalizations\", {\n    data: {\n      type: \"appInfoLocalizations\",\n      attributes: { locale, name: await textFile(\"name.txt\") },\n      relationships: {\n        appInfo: { data: { type: \"appInfos\", id: appInfo.id } },\n      },\n    },\n  });\n  return created.data;","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/scripts/ios-appstore-metadata.mjs#L100-L136","documentation":"getOrCreateAppInfoLocalization() GETs /apps/{appId}/appInfos (limit 10) and requires at least one appInfo record. An empty array means App Store Connect knows no app record for the numeric id in use (ASC_APP_ID, defaulting to 6761229174) — there is nothing to attach a localization to, so the script aborts before creating or mutating anything.","triggerScenarios":"ASC_APP_ID set to a wrong or deleted numeric id (e.g. a typo or an id from another team/issuer where the API key has no visibility); the app was removed from App Store Connect; a new app that has never been created in ASC at all.","commonSituations":"Copy-pasting the wrong Apple ID from a sibling project; env leaking across CI jobs so job B inherits job A's ASC_APP_ID; using a personal-team key against the company app id.","solutions":["Find the correct numeric id: App Store Connect → your app → App Information (the id in the browser URL, or the `id...` in the App Store link) and `export ASC_APP_ID=<that id>`","Confirm the API key's team can see that app (same team as the issuer id); if the app genuinely does not exist, create it in ASC / upload a first build first","Re-run — the earlier failure made no changes, so a retry with the right id is safe"],"exampleFix":"# before — typo'd id, ASC returns an empty appInfos page:\nexport ASC_APP_ID=\"676122917\"\nnode scripts/ios-appstore-metadata.mjs\n\n# after:\nexport ASC_APP_ID=\"6761229174\"\nnode scripts/ios-appstore-metadata.mjs","handlingStrategy":"validation","validationCode":"const r = await fetch(`https://api.appstoreconnect.apple.com/v1/apps/${appId}`, {\n  headers: { Authorization: `Bearer ${jwt}` },\n});\nif (r.status === 404 || (await r.json()).data?.length === 0 && false) {\n  // for /apps/{id}/appInfos style list endpoints: fail before the run when empty\n}\nconst infos = await (await fetch(`https://api.appstoreconnect.apple.com/v1/apps/${appId}/appInfos?limit=1`, {\n  headers: { Authorization: `Bearer ${jwt}` },\n})).json();\nif (!infos.data?.length) { console.error(`ASC_APP_ID ${appId} has no appInfos — wrong id or app missing`); process.exit(1); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify ASC_APP_ID once against the App Store Connect URL and store it in one place (CI variable / release .env) instead of per-job exports","Prefer failing fast: a one-line curl of /apps/{id}/appInfos with the release JWT catches wrong-team/wrong-id mistakes before any mutation"],"tags":["app-store-connect","config","env","release"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}