ComposioHQ/composio · error · Error

Missing platform-imessage submodule at ${submoduleRelativePa

Error message

Missing platform-imessage submodule at ${submoduleRelativePath}. Run: git submodule update --init --recursive -- ${submoduleRelativePath}

What it means

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.

Source

Thrown at ts/packages/cli-local-tools/scripts/build-beeper-imessage-binaries.ts:79

  return `"AX${match[1]}"`;
};

const ensurePlatform = () => {
  if (process.platform !== 'darwin') {
    throw new Error(
      'Building Beeper iMessage local-tool binaries requires macOS and the Swift toolchain.'
    );
  }
};

const ensureSubmodule = async () => {
  if (await exists(path.join(submodulePath, 'Package.swift'))) return;

  console.log(`Initializing ${submoduleRelativePath} submodule...`);
  await $`git submodule update --init --recursive -- ${submoduleRelativePath}`.cwd(repoRoot);

  if (!(await exists(path.join(submodulePath, 'Package.swift')))) {
    throw new Error(
      `Missing platform-imessage submodule at ${submoduleRelativePath}. Run: git submodule update --init --recursive -- ${submoduleRelativePath}`
    );
  }
};

const getSubmoduleCommit = async (): Promise<string> =>
  (await $`git rev-parse HEAD`.cwd(submodulePath).text()).trim();

const getSubmoduleVersion = async (): Promise<string> => {
  const packageJson = await readJson<{ version?: string }>(
    path.join(submodulePath, 'package.json')
  );
  return packageJson.version ?? 'unknown';
};

const copyLicense = async () => {
  const licenseCandidates = ['license.txt', 'LICENSE.txt', 'LICENSE', 'LICENSE.md'];
  for (const candidate of licenseCandidates) {

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Run `git submodule update --init --recursive -- <submoduleRelativePath>` manually to see the real git error.
  2. Verify .gitmodules URL is reachable and you have credentials; then retry the build script.
  3. If the submodule path is wrong, fix it in .gitmodules and re-sync (`git submodule sync`).
Defensive patterns

Strategy: validation

Validate before calling

import { exists } from 'fs/promises';
import path from 'path';
const hasSubmodule = await exists(path.join(repoRoot, submoduleRelativePath, 'Package.swift'));

Try / catch

try {
  await main();
} catch (e) {
  if (e instanceof Error && e.message.includes('submodule')) {
    // print the git recovery command and exit non-zero
  }
}

Prevention

When it happens

Trigger: 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).

Common situations: Shallow clones in CI without submodule init; corporate proxies blocking the submodule remote; renamed/moved submodule remotes.

Related errors


AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28). Data as JSON: /api/errors/2fad7f45913e9802. Report an issue: GitHub.