multica-ai/multica · error · Error

mint PAT: target API URL not set

Error message

mint PAT: target API URL not set

What it means

Thrown by prepareHermesHome when params demand an existing source home (sourceMustExist) and os.Stat on the resolved shared home fails or the path is not a directory. The resolved home is either the explicitly configured source or the platform default (platformDefaultHermesHome()). The message names the exact path and the hermes CLI command to fix it.

Source

Thrown at apps/desktop/src/main/daemon-manager.ts:603

    }
    case "restart":
      console.log(
        `[daemon] CLI version mismatch (bundled=${bundled} running=${running?.cli_version}) — restarting daemon`,
      );
      pendingVersionRestart = false;
      await restartDaemon();
      return "restarted";
  }
}

/**
 * Exchange the user's JWT for a long-lived PAT via POST /api/tokens. The
 * daemon needs a PAT (or `mul_` / `mdt_` token) because JWTs expire in 30
 * days and signatures are tied to a specific backend instance.
 */
async function mintPat(jwt: string): Promise<string> {
  if (!targetApiBaseUrl) {
    throw new Error("mint PAT: target API URL not set");
  }
  const url = `${targetApiBaseUrl.replace(/\/+$/, "")}/api/tokens`;
  const res = await fetch(url, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${jwt}`,
    },
    // Omit expires_in_days → server treats as null → non-expiring PAT.
    body: JSON.stringify({ name: "Multica Desktop" }),
  });
  if (!res.ok) {
    const body = await res.text().catch(() => "");
    // Attach the status so callers can tell a genuine auth rejection (401 — the
    // session token is dead) apart from a transient failure (5xx, etc.) without
    // string-matching the message.
    throw Object.assign(
      new Error(`mint PAT failed: ${res.status} ${res.statusText} ${body}`),

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. Run `hermes profile create` (or otherwise materialize the home) on the daemon host at the exact path shown in the error message.
  2. Correct the agent's HermesSourceHome configuration to the real home directory path.
  3. In containers, mount the host's hermes home at the path the daemon expects.
  4. If the home genuinely may be absent, unset the must-exist flag (HermesSourceMustExist) so a missing source degrades instead of failing.

Example fix

# before: home missing → prepare fails
$ ls /home/user/.hermes
ls: cannot access '/home/user/.hermes': No such file or directory

# after
$ hermes profile create   # materializes the platform default home
$ ls -d /home/user/.hermes
Defensive patterns

Strategy: validation

Validate before calling

if sourceMustExist {
    fi, err := os.Stat(strings.TrimSpace(sourceHome))
    if err != nil || !fi.IsDir() {
        return fmt.Errorf("hermes home missing — run `hermes profile create` or fix %s", sourceHome)
    }
}

Try / catch

if err := prepareHermesHome(...); err != nil {
    if strings.Contains(err.Error(), "not found (create it with") {
        // actionable: create the profile home, then re-run prepare — deterministic fix, no retry loop
    }
}

Prevention

When it happens

Trigger: prepareHermesHome is called with sourceMustExist == true and sharedHome (HermesSourceHome after TrimSpace, or the platform default when empty) does not exist, is a file, or is not readable by the daemon user.

Common situations: Hermes never installed/profile never created on the daemon host; HermesSourceHome pointing at a home directory that was moved or deleted; running the daemon in a container without mounting the host's hermes home; wrong $HOME so platformDefaultHermesHome() resolves elsewhere.

Related errors


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