Skip to content

serve --acp initialize response violates the ACP schema: sessionCapabilities.list is a boolean instead of an object — strict clients (JetBrains IDEA) fail to connect #5969

Description

@Lujc0523

serve --acp initialize response violates the ACP schema: sessionCapabilities.list is a boolean instead of an object — strict clients (JetBrains IDEA) fail to connect

Repo target: Hmbown/CodeWhale


Environment

  • Package / version: codewhale npm wrapper 0.9.12, native binary codewhale 0.9.12 (Linux x64)
  • Command under test: codewhale serve --acp (ACP v1 server over stdio, newline-delimited JSON-RPC 2.0)
  • Client: JetBrains IntelliJ IDEA 2026.2 built-in ACP client (com.intellij.platform.acp, ml-llm AI Assistant), registered via ~/.jetbrains/acp.json:
{
  "codewhale": {
    "command": "/home/lujc/.npm-global/bin/codewhale",
    "args": ["serve", "--acp"]
  }
}

Summary

Since 0.9.12, the initialize response of codewhale serve --acp advertises session capabilities as boolean literals:

"sessionCapabilities": { "list": true, "load": true }

Per the ACP schema, SessionCapabilities.list is typed as SessionListCapabilities | null — an object ("By supplying {} it means that the agent supports listing of sessions"), never a boolean. ACP clients with strictly-typed deserializers — notably JetBrains IDEA's built-in ACP client (Kotlin agent-client-protocol model, kotlinx.serialization) — throw a JsonDecodingException while parsing the handshake, treat the failure as non-recoverable, and kill the agent process. Result: codewhale cannot be used from IDEA at all in 0.9.12. The same client connects fine to 0.9.11 and to other ACP agents.

Reproduction

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{}}}' \
  | timeout 15 codewhale serve --acp

Actual behavior

The initialize response contains boolean capability values:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": 1,
    "agentCapabilities": {
      "loadSession": true,
      "modelSelection": true,
      "promptCapabilities": { "image": false, "audio": false, "embeddedContext": true },
      "mcpCapabilities": { "http": false, "sse": false },
      "sessionCapabilities": { "list": true, "load": true }
    },
    "agentInfo": { "name": "codewhale", "title": "codewhale", "version": "0.9.12" },
    "authMethods": [ /* ... */ ]
  }
}

Note two schema deviations in sessionCapabilities:

  1. "list": true — must be a SessionListCapabilities object ({} means "supported", absent/null means "not supported"). This is the one that breaks strict clients.
  2. "load": true — not a defined property of SessionCapabilities in the current schema (session/load support is advertised via the top-level loadSession boolean, which codewhale already sets correctly). Currently harmless for lenient clients, but should be removed.

Client-side failure (JetBrains IDEA 2026.2, idea.log)

WARN - AcpSessionLifecycleManager - Failed to initialize ACP session for chat 01fb1342-..., error:
kotlinx.serialization.json.internal.JsonDecodingException: Expected JsonObject, but had JsonLiteral
as the serialized body of com.agentclientprotocol.model.SessionListCapabilities at element: $.list
JSON input: true
	at com.agentclientprotocol.model.SessionListCapabilities$$serializer.deserialize(Capabilities.kt:130)
	at com.agentclientprotocol.model.SessionCapabilities$$serializer.deserialize(Capabilities.kt:183)
	at com.agentclientprotocol.model.AgentCapabilities$$serializer.deserialize(Capabilities.kt:248)
	at com.agentclientprotocol.model.InitializeResponse$$serializer.deserialize(Requests.kt:555)
	...

AcpSessionLifecycleManager - handleSessionConnectionFailed for agent=acp.codewhale, recoverable=false,
message=Failed to initialize ACP session. Error: Expected JsonObject, but had JsonLiteral ... at element: $.list
AcpServerProcessHandlerImpl - [codewhale] Sending SIGTERM (graceful shutdown)...

The client marks the failure recoverable=false and terminates the agent process ~60 ms after spawning it, so the user just sees a connection error in the IDE.

Expected behavior

Advertise the capability with the schema-defined object shape:

"sessionCapabilities": { "list": {} }

(or omit list entirely if session/list is not supported).

Reference: working agents, same client, same request

Both connect successfully in IDEA 2026.2:

  • Kimi Code CLI 0.41.0 (kimi acp): "sessionCapabilities":{"list":{},"resume":{},"close":{},"delete":{},"fork":{},"additionalDirectories":{}}
  • Reasonix v1.38.1 (reasonix acp): "sessionCapabilities":{"list":{},"resume":{},"close":{},"delete":{}}

Regression window

  • IDEA logs from 2026-09-04 show a working codewhale ACP session (0.9.11; initialize/session/new/session/prompt all succeeded, see also codewhale-acp-session-config-issue.md filed against 0.9.11).
  • After upgrading to 0.9.12 (2026-09-07), every connection attempt fails at the handshake. So the sessionCapabilities advertisement was introduced/changed in 0.9.12 with the wrong JSON shape.

Suggested fix

In the serve --acp initialize handler:

  1. Emit sessionCapabilities.list as an object: "list": {} (or use the schema/Rust-SDK type for SessionListCapabilities instead of a raw boolean).
  2. Drop the non-schema "load": true field from sessionCapabilities; loadSession: true at the top level already covers it.
  3. Consider validating the initialize response against the published ACP JSON schema in CI — this class of mistake is caught instantly by a schema check, and strict clients (JetBrains) break hard on it.

Notes

  • Framing: codewhale speaks newline-delimited JSON-RPC (Zed ACP style); sending Content-Length-headered framing only produces a -32700 parse error line per header/body line.
  • The failure is purely in handshake deserialization; the agent process itself is healthy and codewhale --version / interactive use are unaffected.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions