chenhg5/cc-connect · error
%s
Error message
%s
What it means
After the kimi CLI process exits, readLoop checks the wait error; on non-zero exit with non-empty stderr it logs the failure and emits core.EventError whose message is exactly the trimmed stderr text (`fmt.Errorf("%s", stderrMsg)`). The message content is kimi's own diagnostic output, so the concrete cause (auth, quota, bad flag) is embedded in the error string.
Source
Thrown at agent/kimi/session.go:308
break
}
}
if scanErr != nil {
slog.Error("kimiSession: scanner error", "error", scanErr)
evt := core.Event{Type: core.EventError, Error: fmt.Errorf("read stdout: %w", scanErr)}
select {
case ks.events <- evt:
case <-ks.ctx.Done():
return
}
}
if waitErr != nil {
stderrMsg := strings.TrimSpace(stderrBuf.String())
if stderrMsg != "" {
slog.Error("kimiSession: process failed", "error", waitErr, "stderr", stderrMsg)
evt := core.Event{Type: core.EventError, Error: fmt.Errorf("%s", stderrMsg)}
select {
case ks.events <- evt:
case <-ks.ctx.Done():
return
}
return
}
}
// Flush any remaining pending messages as text and send result event.
ks.flushPendingAsText()
evt := core.Event{Type: core.EventResult, SessionID: ks.CurrentSessionID(), Done: true}
select {
case ks.events <- evt:
case <-ks.ctx.Done():
}
}
View on GitHub (pinned to 4000b2338a)
Solutions
- Read the event's Error text — it is kimi's stderr and names the real cause; act on that (fix key, quota, or flags).
- Reproduce manually in the workDir: `kimi --prompt "test"` and compare stderr.
- Align CLI version with the adapter: upgrade/downgrade kimi or update flag construction in agent/kimi/session.go.
- Verify credentials/env in the daemon context (systemd Environment= / EnvironmentFile) so the API key is actually present.
Example fix
// symptom $ kimi --prompt "hi" Error: unauthorized: invalid api key // fix for daemons # /etc/systemd/system/cc-connect.service [Service] EnvironmentFile=/etc/cc-connect/env # contains KIMI_API_KEY=...
Defensive patterns
Strategy: try-catch
Validate before calling
// validate CLI + credentials before opening sessions
out, err := exec.Command(kimiCmd, "--version").CombinedOutput()
if err != nil {
return fmt.Errorf("kimi CLI unusable: %v: %s", err, out)
}
// ensure API key present in this process env
if os.Getenv("KIMI_API_KEY") == "" {
return errors.New("KIMI_API_KEY not set for daemon environment")
} Type guard
func isKimiProcessFailure(err error) bool {
return err != nil && !strings.Contains(err.Error(), "session is closed")
} // event Error text is kimi's raw stderr — inspect it for auth/quota causes Try / catch
for evt := range sess.Events() {
if evt.Type == core.EventError {
msg := evt.Error.Error()
switch {
case strings.Contains(msg, "unauthorized"), strings.Contains(msg, "api key"):
fixCredentialsAndRecreate()
case strings.Contains(msg, "quota"), strings.Contains(msg, "rate limit"):
backoffAndRetry()
default:
surfaceToUser(msg)
}
}
} Prevention
- Provide the kimi API key via the daemon's EnvironmentFile, not just your shell
- Pin the kimi CLI version; check flag changes before upgrading the CLI
- Monitor quota usage to anticipate rate-limit failures
- Test `kimi --prompt test` under the daemon user after every deploy
When it happens
Trigger: The kimi CLI exits non-zero while handling a prompt: invalid/missing API key, quota or rate limit exhausted, unsupported/renamed CLI flags, incompatible CLI version, or backend/network failure reported by the CLI.
Common situations: Expired or missing kimi API key in the daemon environment; kimi CLI upgraded with changed flags that this adapter still passes; hitting plan quota mid-session; network outage reaching the kimi backend.
Related errors
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/2f5addfbf49b1194.
Report an issue: GitHub.