{"record":{"id":"2f5addfbf49b1194","repo":"chenhg5/cc-connect","slug":"s-2f5add","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/kimi/session.go","lineNumber":308,"sourceCode":"\t\t\tbreak\n\t\t}\n\t}\n\n\tif scanErr != nil {\n\t\tslog.Error(\"kimiSession: scanner error\", \"error\", scanErr)\n\t\tevt := core.Event{Type: core.EventError, Error: fmt.Errorf(\"read stdout: %w\", scanErr)}\n\t\tselect {\n\t\tcase ks.events <- evt:\n\t\tcase <-ks.ctx.Done():\n\t\t\treturn\n\t\t}\n\t}\n\n\tif waitErr != nil {\n\t\tstderrMsg := strings.TrimSpace(stderrBuf.String())\n\t\tif stderrMsg != \"\" {\n\t\t\tslog.Error(\"kimiSession: process failed\", \"error\", waitErr, \"stderr\", stderrMsg)\n\t\t\tevt := core.Event{Type: core.EventError, Error: fmt.Errorf(\"%s\", stderrMsg)}\n\t\t\tselect {\n\t\t\tcase ks.events <- evt:\n\t\t\tcase <-ks.ctx.Done():\n\t\t\t\treturn\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Flush any remaining pending messages as text and send result event.\n\tks.flushPendingAsText()\n\tevt := core.Event{Type: core.EventResult, SessionID: ks.CurrentSessionID(), Done: true}\n\tselect {\n\tcase ks.events <- evt:\n\tcase <-ks.ctx.Done():\n\t}\n}\n","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/kimi/session.go#L290-L326","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// symptom\n$ kimi --prompt \"hi\"\nError: unauthorized: invalid api key\n\n// fix for daemons\n# /etc/systemd/system/cc-connect.service\n[Service]\nEnvironmentFile=/etc/cc-connect/env  # contains KIMI_API_KEY=...","handlingStrategy":"try-catch","validationCode":"// validate CLI + credentials before opening sessions\nout, err := exec.Command(kimiCmd, \"--version\").CombinedOutput()\nif err != nil {\n    return fmt.Errorf(\"kimi CLI unusable: %v: %s\", err, out)\n}\n// ensure API key present in this process env\nif os.Getenv(\"KIMI_API_KEY\") == \"\" {\n    return errors.New(\"KIMI_API_KEY not set for daemon environment\")\n}","typeGuard":"func isKimiProcessFailure(err error) bool {\n    return err != nil && !strings.Contains(err.Error(), \"session is closed\")\n} // event Error text is kimi's raw stderr — inspect it for auth/quota causes","tryCatchPattern":"for evt := range sess.Events() {\n    if evt.Type == core.EventError {\n        msg := evt.Error.Error()\n        switch {\n        case strings.Contains(msg, \"unauthorized\"), strings.Contains(msg, \"api key\"):\n            fixCredentialsAndRecreate()\n        case strings.Contains(msg, \"quota\"), strings.Contains(msg, \"rate limit\"):\n            backoffAndRetry()\n        default:\n            surfaceToUser(msg)\n        }\n    }\n}","preventionTips":["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"],"tags":["go","process","stderr","cli"],"backgroundTag":"cli-process-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}