{"record":{"id":"c162021304f55ae3","repo":"chenhg5/cc-connect","slug":"acp-session-prompt-w","errorCode":null,"errorMessage":"acp: session/prompt: %w","messagePattern":"acp: session/prompt: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/acp/session.go","lineNumber":621,"sourceCode":"\n\tsid := s.currentACPSessionID()\n\tif sid == \"\" {\n\t\treturn fmt.Errorf(\"acp: no agent session id\")\n\t}\n\n\tpromptBlocks := []any{\n\t\tmap[string]any{\"type\": \"text\", \"text\": prompt},\n\t}\n\tparams := map[string]any{\n\t\t\"sessionId\": sid,\n\t\t\"prompt\":    promptBlocks,\n\t}\n\n\tslog.Debug(\"acp: sending session/prompt\", \"session_id\", sid, \"prompt_len\", len(prompt))\n\tres, err := s.tr.call(s.ctx, \"session/prompt\", params)\n\tif err != nil {\n\t\ts.emit(core.Event{Type: core.EventError, Error: err})\n\t\treturn fmt.Errorf(\"acp: session/prompt: %w\", err)\n\t}\n\tslog.Debug(\"acp: session/prompt response\", \"session_id\", sid, \"response_len\", len(res), \"response\", string(res))\n\n\t// Text was streamed via session/update; engine aggregates EventText.\n\ts.emit(core.Event{\n\t\tType:      core.EventResult,\n\t\tSessionID: sid,\n\t\tDone:      true,\n\t})\n\treturn nil\n}\n\nfunc (s *acpSession) appendImageRefs(prompt string, images []core.ImageAttachment) string {\n\tattachDir := filepath.Join(s.workDir, \".cc-connect\", \"attachments\")\n\tif err := os.MkdirAll(attachDir, 0o755); err != nil {\n\t\tslog.Warn(\"acp: mkdir attachments failed\", \"error\", err)\n\t\treturn prompt\n\t}","sourceCodeStart":603,"sourceCodeEnd":639,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/acp/session.go#L603-L639","documentation":"Wrapped when the JSON-RPC `session/prompt` call fails while delivering the user's message. The error is also emitted as a core.EventError on the session's event stream so the engine can surface it to the messaging platform, then returned to the caller.","triggerScenarios":"The agent returned a JSON-RPC error for session/prompt (session not found after agent restart, prompt rejected, content policy/limit hit) or the transport call failed — timeout, ctx cancelled, agent process died mid-call.","commonSituations":"Agent restarted and its old session id is stale; prompt too large or containing content the agent refuses; network/socket hiccup to a remote ACP agent; user-cancelled context; agent hit rate limits.","solutions":["Read the wrapped cause: if it indicates an unknown session, start a new session and retry the prompt.","Check the emitted EventError on the stream — agent-side refusal messages (quota, safety) usually carry the reason.","Increase the prompt timeout or reduce the prompt size if it timed out on long turns.","If the agent process died, check the process-exit stderr log, fix the crash cause, and recreate the session.","Retry once on transient transport errors before failing the user message."],"exampleFix":"// before: one-shot send, user gets raw failure\nif err := sess.Send(prompt, mid, nil, nil); err != nil {\n    return err\n}\n// after: detect stale session and recreate once\nif err := sess.Send(prompt, mid, nil, nil); err != nil {\n    sess, rerr := agent.StartSession(ctx, core.ContinueSession, nil)\n    if rerr != nil { return rerr }\n    return sess.Send(prompt, mid, nil, nil)\n}","handlingStrategy":"retry","validationCode":"// preflight: only send on an initialized, live session with a known id\nif sess == nil || !sessionAlive(sess) || currentACPID(sess) == \"\" {\n    return fmt.Errorf(\"session not ready for prompt\")\n}","typeGuard":"func ready(sess *acpSession) bool {\n    return sess.alive.Load() && sess.currentACPSessionID() != \"\"\n}","tryCatchPattern":"if err := sess.Send(prompt, mid, nil, nil); err != nil {\n    if strings.Contains(err.Error(), \"acp: session/prompt\") {\n        select {\n        case ev := <-sess.Events():\n            if ev.Type == core.EventError { slog.Warn(\"agent refused prompt\", \"cause\", ev.Error) }\n        default:\n        }\n        // recreate session and retry once for transient/stale-session causes\n    }\n    return err\n}","preventionTips":["Subscribe to EventError to capture agent-side refusal reasons (quota, safety, stale session).","Keep prompts within agent size limits; split very large messages.","Use ContinueSession/start-new-session handling when the agent restarts between turns.","Set realistic prompt timeouts for long agent turns."],"tags":["acp","session-prompt","json-rpc","agent-process"],"backgroundTag":"api-request-failed","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"}