SIGN IN SIGN UP

MUL-6656 fix(daemon): explain why repo checkout auth failed (#7520) (#7524)

* fix(daemon): explain why repo checkout auth failed (MUL-6656)

`/repo/checkout` answered every auth failure with one line —
"repo checkout requires an active task credential" — and logged nothing.
That single message covers two unrelated failures with opposite fixes, so
GH #7520 spent ~13 hours being investigated as a credential-issuance race
when it was a stale `multica` binary on PATH.

Split the two cases and make each one self-explanatory:

- No Authorization header at all. Only a CLI older than v0.4.30 does this
  (the header and this check landed together in #7205), so it is permanent,
  not flaky. The rejection now names the minimum version, the daemon's own
  version, `which -a multica`, the absolute path of a version-matched
  binary, and the upgrade command.
- A token no active task owns — the task finished, or the daemon restarted
  under a still-running agent. Says that instead, and deliberately does not
  advise an upgrade, which would be wrong for an up-to-date CLI.

Both paths now emit a WARN naming the reason, so the failure is greppable
in daemon.log instead of existing only on the agent's stderr. The token is
never logged.

The compatibility advice lives in the daemon on purpose: the clients that
hit the no-credential case are by definition too old to receive any
CLI-side fix, and the daemon is the only component on this path guaranteed
to be current.

Co-authored-by: multica-agent <github@multica.ai>

* fix(daemon): make repo checkout self-help portable and honest

Review found two ways the new rejection message could mislead the very
readers it was written for.

Platform-specific commands. The endpoint runs on Windows and Linux too,
but the message hardcoded `which -a multica` and `brew upgrade
multica-ai/tap/multica` — unrunnable for a Windows reader and wrong for a
Linux direct install. Enumerating copies now follows GOOS (`where.exe` on
Windows), and the upgrade instruction is `multica update`, which already
detects Homebrew vs. direct installs on every platform.

An unverified version claim. The message called the daemon's own binary a
"version-matched copy", but resolveSelfExecutable only reports where this
process started — not what is on disk now. The daemon deliberately
supports the binary being replaced out of band while a restart is deferred
(pollSelfVersion), so that claim can be false exactly in a version-skew
situation, handing a stale-binary victim a second stale binary. It now
states provenance, asks the reader to check that copy's version, and — when
a reload is already pending — says the on-disk copy drifted and quotes the
detail the daemon already has.

Also assert the log level explicitly, so a later downgrade to Debug, which
daemon.log filters out by default, cannot silently pass the test that
exists to guarantee the failure is greppable.

Co-authored-by: multica-agent <github@multica.ai>

* docs(daemon): correct self-reload reference and message wording

Review nits: the comment cited pollSelfVersion, which does not exist —
the deferred-restart logic lives in trySelfReload. Also reword the
drifted-binary clause to "has since changed".

Co-authored-by: multica-agent <github@multica.ai>

---------

Co-authored-by: J <bohan@devv.ai>
Co-authored-by: multica-agent <github@multica.ai>
B
Bohan Jiang committed
f7dd08f30476e5748f2975b8cee6bda89ee47c67
Parent: 11ab949
Committed by GitHub <noreply@github.com> on 8/25/2026, 5:17:31 AM