multica-ai/multica · error

repo is configured but not synced

Error message

repo is configured but not synced

What it means

Same repo-access check as 878 but with no recorded sync error: the repo list refreshed fine, the workspace reports successful sync, yet the requested repoURL is absent from the synced repos. Typically a mismatch between the configured URL and the synced URL (or the server hasn't actually configured that repo for this workspace despite client-side caching).

Source

Thrown at server/internal/daemon/daemon.go:3394

	if d.repoCache.Lookup(workspaceID, repoURL) != "" {
		return nil
	}

	d.syncWorkspaceReposContext(ctx, workspaceID, resp.Repos)
	if err := ctx.Err(); err != nil {
		return context.Cause(ctx)
	}

	if d.repoCache.Lookup(workspaceID, repoURL) != "" {
		return nil
	}

	if syncErr := d.workspaceLastRepoSyncErr(workspaceID); syncErr != "" {
		return fmt.Errorf("repo is configured but not synced: %s", syncErr)
	}

	return fmt.Errorf("repo is configured but not synced")
}

// DefaultTokenRenewalInterval is how often the daemon asks the server to
// extend its PAT. The server-side threshold is 7 days of remaining lifetime;
// polling every ~3 days gives at least two chances to renew before the
// window closes, so a single failed call (network blip, server restart) does
// not push the token out of the renewal window.
const DefaultTokenRenewalInterval = 3 * 24 * time.Hour

// preflightAuth runs the two auth-sensitive startup steps in their
// required order: a synchronous PAT renewal first, then the initial
// workspace sync. The order matters — running tryRenewToken before any
// other API call is what surfaces a user-actionable "run multica login"
// WARN when the PAT is already revoked or expired. If we let the
// workspace sync go first, its 401 would short-circuit Run before the
// renewal loop's first tick ever fires, and the operator would see only
// a generic auth failure in the workspace-sync log with no hint that
// re-login is the fix.

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. Compare the task's repoURL string with the workspace's configured repo URLs exactly (scheme, host, path, .git suffix)
  2. Normalize both sides to one URL form (e.g. always https://host/org/repo.git) before submitting tasks
  3. Re-run the workspace sync and retry once a newly added repo has finished its first clone
  4. If the repo was intentionally removed, update the task/client to stop referencing it

Example fix

// before
if err := task.RepoURL == wantURL { ... } // exact string compare, SSH vs https mismatch

// after: canonicalize both URLs before comparing
func canonicalRepoURL(raw string) string {
    u := strings.TrimSuffix(raw, ".git")
    u = strings.Replace(u, "git@github.com:", "github.com/", 1)
    u = strings.TrimPrefix(u, "ssh://")
    return strings.TrimPrefix(u, "https://")
}
if canonicalRepoURL(task.RepoURL) != canonicalRepoURL(wantURL) { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Canonicalize repo URLs before comparing/submission.
func canonicalRepoURL(raw string) string {
    u := strings.TrimSuffix(strings.TrimSpace(raw), ".git")
    u = strings.Replace(u, "git@github.com:", "github.com/", 1)
    u = strings.TrimPrefix(u, "ssh://")
    u = strings.TrimPrefix(u, "https://")
    u = strings.TrimPrefix(u, "http://")
    return strings.ToLower(u)
}

// reject task dispatch when canonical forms differ
if canonicalRepoURL(taskRepo) != canonicalRepoURL(configuredRepo) {
    return fmt.Errorf("repo %q not in workspace config (did you mean %q?)", taskRepo, configuredRepo)
}

Try / catch

On this error, do not retry: fetch the workspace's configured repo list, show it next to the requested URL, and fail the task with a 'URL form mismatch or repo not configured' message.

Prevention

When it happens

Trigger: A task references repoURL 'git@github.com:org/repo.git' while the workspace synced 'https://github.com/org/repo' — same repo, different URL form — or the repo was recently removed from the workspace config server-side and a stale client still assumes access.

Common situations: SSH vs https URL forms for the same repo, trailing '.git' differences, repo removed from workspace configuration after tasks were queued, or newly added repos whose first sync hasn't completed.

Related errors


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/b6d11bb981deb678. Report an issue: GitHub.