{"record":{"id":"242aa39adeba4dbf","repo":"chenhg5/cc-connect","slug":"s-242aa3","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/reasonix/session.go","lineNumber":429,"sourceCode":"\t\t\tqs = append(qs, core.UserQuestion{\n\t\t\t\tQuestion:    q.Prompt,\n\t\t\t\tHeader:      q.Header,\n\t\t\t\tOptions:     opts,\n\t\t\t\tMultiSelect: q.Multi,\n\t\t\t})\n\t\t}\n\t\ts.emit(core.Event{\n\t\t\tType:      core.EventPermissionRequest,\n\t\t\tRequestID: we.Ask.ID,\n\t\t\tQuestions: qs,\n\t\t})\n\n\tcase \"turn_done\":\n\t\ts.flushThinking()\n\t\ts.inTurn.Store(false)\n\t\ts.mu.Lock()\n\t\tif we.Err != \"\" {\n\t\t\ts.errTurn = fmt.Errorf(\"%s\", we.Err)\n\t\t}\n\t\terrTurn := s.errTurn\n\t\ts.mu.Unlock()\n\n\t\ts.emit(core.Event{Type: core.EventResult, Done: true, Error: errTurn})\n\t\ts.turnDone <- struct{}{}\n\n\tcase \"notice\":\n\t\ts.flushThinking()\n\t\ts.emit(core.Event{Type: core.EventText, Content: \"[Notice] \" + we.Text})\n\n\tcase \"usage\", \"compaction_started\", \"compaction_done\":\n\t\t// Informational, no user-visible event needed\n\n\tdefault:\n\t\tslog.Debug(\"reasonix: unhandled event\", \"kind\", we.Kind)\n\t}\n}","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/reasonix/session.go#L411-L447","documentation":"In agent/reasonix, when the serve stream emits a 'turn_done' event carrying a non-empty Err string, the session stores it as s.errTurn and emits a core.EventResult with Done=true and that error. The string is formatted into an error with fmt.Errorf(\"%s\", we.Err). This is how the reasonix agent surfaces a failed turn to the engine and ultimately to the messaging platform.","triggerScenarios":"The reasonix serve endpoint's SSE stream sends {\"type\":\"turn_done\",\"error\":\"...\"} with a non-empty error field — i.e. the underlying reasonix agent process/turn failed after streaming started.","commonSituations":"Reasonix CLI crashed mid-turn, invalid model name, context window exceeded, agent-internal tool failure, or the serve process returned a turn-level error after partial output was already streamed to the user.","solutions":["Read the wrapped Err text in the emitted EventResult — it carries the reasonix-side failure message; fix the underlying agent issue it reports","Check the reasonix serve process logs around the failing turn for a stack trace or exit reason","Verify the reasonix serve endpoint is a compatible version and the model/config passed at session creation is valid","Retry the turn; if it reproduces, reproduce with a minimal prompt to isolate agent-side vs request-side causes"],"exampleFix":"// engine side: surface the wrapped error to the user\nif ev.Error != nil {\n    reply := fmt.Sprintf(\"turn failed: %v\", ev.Error)\n    p.Reply(chatID, reply)\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Go: inspect the emitted event\nfor ev := range sess.Events() {\n    if ev.Type == core.EventResult && ev.Error != nil {\n        slog.Error(\"reasonix turn failed\", \"err\", ev.Error)\n        notifyUser(chatID, fmt.Sprintf(\"turn failed: %v\", ev.Error))\n    }\n}","preventionTips":["Keep the reasonix serve process healthy and version-matched to the adapter","Surface EventResult.Error to users instead of silently ending the turn","Log every turn-level error with the prompt for later triage"],"tags":["agent","sse","turn-failure"],"backgroundTag":"upstream-api-error","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}