tinyhumansai/openhuman · error · Error

Failed to list branches

Error message

Failed to list branches

What it means

BranchPicker load: calls composioExecute('GITHUB_LIST_BRANCHES', { owner, repo: repoName, per_page: 100 }) guarded by a request sequence counter (stale responses for a changed repo are dropped, not errors). If the action returns successful:false it throws res.error when present, else 'Failed to list branches'. Parsing afterwards tolerates several Composio wrapper shapes (details, data.details, branches, items, bare array).

Solutions

  1. Confirm owner/repo are correct and the connected GitHub account can see the repo
  2. Reconnect GitHub via Composio if the token was revoked
  3. Inspect res.error in the network/console for GitHub's message before retrying
  4. Retry the selection after rate limits cool down
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate owner/repo shape before firing the Composio action
if (!owner.trim() || !repoName.trim() || /[\/\s]/.test(repoName)) {
  setError('Select a valid owner/repo first');
  return;
}

Try / catch

try {
  const res = await composioExecute('GITHUB_LIST_BRANCHES', { owner, repo: repoName, per_page: 100 });
  if (seq !== requestSeqRef.current) return; // stale response for a different repo - not an error
  if (!res.successful) throw new Error(res.error ?? 'Failed to list branches');
  // unwrap details / data.details / branches / items / array ...
} catch (err) {
  setError(err instanceof Error ? err.message : String(err));
}

Prevention

When it happens

Trigger: The GITHUB_LIST_BRANCHES action fails: owner/repo pair wrong or inaccessible (private repo the token cannot read), token revoked/expired, GitHub rate limit, or the repo has no default access via the connected account.

Common situations: Typo in the repo name assembled by a parent picker; private/org repo the Composio connection was never granted; rapid repo switching where an in-flight request fails; per_page: 100 hiding branches on huge repos is NOT this error - that is silent truncation.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/4544b526f0e561bf. Report an issue: GitHub.

Appendix: source

Thrown at app/src/components/skills/inputs/BranchPicker.tsx:72

      setError(null);
      return;
    }
    const [owner, repoName] = repo.split('/');
    if (!owner || !repoName) {
      setBranches([]);
      return;
    }
    const seq = ++requestSeqRef.current;
    setLoading(true);
    setError(null);
    try {
      const res = await composioExecute('GITHUB_LIST_BRANCHES', {
        owner,
        repo: repoName,
        per_page: 100,
      });
      if (seq !== requestSeqRef.current) return;
      if (!res.successful) throw new Error(res.error ?? 'Failed to list branches');
      // Composio wraps GitHub branch data in a few different shapes
      // (details, data.details, branches, items, direct array under data) —
      // probe the same way DevWorkflowPanel does.
      const raw = res.data;
      let list: GhBranch[] = [];
      if (Array.isArray(raw)) {
        list = raw as GhBranch[];
      } else if (raw && typeof raw === 'object') {
        const obj = raw as Record<string, unknown>;
        const dataObj = obj.data as Record<string, unknown> | undefined;
        const arr =
          (obj.details as unknown[] | undefined) ??
          (dataObj?.details as unknown[] | undefined) ??
          (obj.branches as unknown[] | undefined) ??
          (obj.items as unknown[] | undefined) ??
          (dataObj as unknown[] | undefined);
        if (Array.isArray(arr)) {
          list = arr as GhBranch[];

View on GitHub (pinned to 7491200858)