multica-ai/multica · error
refresh workspace repos: %w
Error message
refresh workspace repos: %w
What it means
The daemon's repo-access check wraps a failed call to refreshWorkspaceRepos — the server API call that lists a workspace's configured repositories failed (network error, 5xx, or auth expiry). Downstream logic needs that list to decide whether a requested repoURL is allowed, so the transport failure is surfaced rather than treated as 'not configured'.
Source
Thrown at server/internal/daemon/daemon.go:3370
//
// - cacheHitOnEntry=false but cache hit *after* we acquire the mutex:
// a sibling goroutine on a concurrent cold-miss already refreshed
// and populated the cache. We can skip the duplicate refresh — the
// sibling's refresh is fresh enough for our gate read.
cacheHitOnEntry := d.workspaceRepoAllowed(workspaceID, repoURL) && d.repoCache.Lookup(workspaceID, repoURL) != ""
if err := ws.repoRefreshMu.Lock(ctx); err != nil {
return err
}
defer ws.repoRefreshMu.Unlock()
if !cacheHitOnEntry && d.workspaceRepoAllowed(workspaceID, repoURL) && d.repoCache.Lookup(workspaceID, repoURL) != "" {
return nil
}
resp, err := d.refreshWorkspaceRepos(ctx, workspaceID)
if err != nil {
return fmt.Errorf("refresh workspace repos: %w", err)
}
if !d.workspaceRepoAllowed(workspaceID, repoURL) {
return ErrRepoNotConfigured
}
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
}View on GitHub (pinned to 2c0912b6ec)
Solutions
- Check server reachability (curl the /api health endpoint) and the daemon's connectivity, then retry — this is usually transient
- If auth-related, re-run 'multica login' and restart the daemon so the token refreshes
- Look at the wrapped error's cause: a 5xx means server-side; a dial error means network/DNS
- If it persists only for one workspace, check that workspace's repo configuration server-side
Defensive patterns
Strategy: retry
Validate before calling
// Cheap reachability probe before the repo-permission path.
if err := pingServer(ctx, c.client, 2*time.Second); err != nil {
return fmt.Errorf("server unreachable, skipping repo check: %w", err)
} Try / catch
Retry with backoff around the wrapped call: unwrap the cause, retry only transient classes (net errors, 502/503/504, context deadline), and fail permanently on auth errors with a login hint.
Prevention
- Keep the daemon's PAT renewal healthy (DefaultTokenRenewalInterval) so tokens never expire
- Monitor server reachability from the daemon host
- Cache the last good repo list to ride out brief outages
When it happens
Trigger: Any task/clone path that goes through repo-permission checking while the server is unreachable, returns 500/503, or the daemon's token expired — i.e. refreshWorkspaceRepos returns err and the repo cache has no hit for the workspace.
Common situations: Server outages or deploys, daemon hibernating through laptop sleep with stale connections, expired PAT after the renewal window was missed, and local firewall/DNS failures.
Related errors
- connect to daemon: %w
- repo is configured but not synced: %s
- repo is configured but not synced
- daemon exited during startup.
- repo is not configured for this workspace
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/60b92834e491f5e3.
Report an issue: GitHub.