{"record":{"id":"2fad7f45913e9802","repo":"ComposioHQ/composio","slug":"missing-platform-imessage-submodule-at-submodule","errorCode":null,"errorMessage":"Missing platform-imessage submodule at ${submoduleRelativePath}. Run: git submodule update --init --recursive -- ${submoduleRelativePath}","messagePattern":"Missing platform-imessage submodule at (.+?)\\. Run: git submodule update --init --recursive -- (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ts/packages/cli-local-tools/scripts/build-beeper-imessage-binaries.ts","lineNumber":79,"sourceCode":"  return `\"AX${match[1]}\"`;\n};\n\nconst ensurePlatform = () => {\n  if (process.platform !== 'darwin') {\n    throw new Error(\n      'Building Beeper iMessage local-tool binaries requires macOS and the Swift toolchain.'\n    );\n  }\n};\n\nconst ensureSubmodule = async () => {\n  if (await exists(path.join(submodulePath, 'Package.swift'))) return;\n\n  console.log(`Initializing ${submoduleRelativePath} submodule...`);\n  await $`git submodule update --init --recursive -- ${submoduleRelativePath}`.cwd(repoRoot);\n\n  if (!(await exists(path.join(submodulePath, 'Package.swift')))) {\n    throw new Error(\n      `Missing platform-imessage submodule at ${submoduleRelativePath}. Run: git submodule update --init --recursive -- ${submoduleRelativePath}`\n    );\n  }\n};\n\nconst getSubmoduleCommit = async (): Promise<string> =>\n  (await $`git rev-parse HEAD`.cwd(submodulePath).text()).trim();\n\nconst getSubmoduleVersion = async (): Promise<string> => {\n  const packageJson = await readJson<{ version?: string }>(\n    path.join(submodulePath, 'package.json')\n  );\n  return packageJson.version ?? 'unknown';\n};\n\nconst copyLicense = async () => {\n  const licenseCandidates = ['license.txt', 'LICENSE.txt', 'LICENSE', 'LICENSE.md'];\n  for (const candidate of licenseCandidates) {","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/ts/packages/cli-local-tools/scripts/build-beeper-imessage-binaries.ts#L61-L97","documentation":"The build depends on the vendored platform-imessage git submodule (detected by the presence of Package.swift). The script tries `git submodule update --init --recursive` itself; if Package.swift still doesn't exist afterwards, the submodule is missing or broken and it aborts with the exact recovery command.","triggerScenarios":"Cloning the repo without --recurse-submodules, or a submodule URL/path mismatch, so platform-imessage is empty and auto-init fails (offline, auth-restricted, or misconfigured .gitmodules).","commonSituations":"Shallow clones in CI without submodule init; corporate proxies blocking the submodule remote; renamed/moved submodule remotes.","solutions":["Run `git submodule update --init --recursive -- <submoduleRelativePath>` manually to see the real git error.","Verify .gitmodules URL is reachable and you have credentials; then retry the build script.","If the submodule path is wrong, fix it in .gitmodules and re-sync (`git submodule sync`)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { exists } from 'fs/promises';\nimport path from 'path';\nconst hasSubmodule = await exists(path.join(repoRoot, submoduleRelativePath, 'Package.swift'));","typeGuard":null,"tryCatchPattern":"try {\n  await main();\n} catch (e) {\n  if (e instanceof Error && e.message.includes('submodule')) {\n    // print the git recovery command and exit non-zero\n  }\n}","preventionTips":["Clone with --recurse-submodules or run submodule init immediately after checkout in CI.","Add a repo bootstrap script that verifies all required submodules before any build."],"tags":["git-submodule","build-script","repo-setup"],"backgroundTag":"git-submodule-not-initialized","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}