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:
"list": true — must be a SessionListCapabilities object ({} means "supported", absent/null means "not supported"). This is the one that breaks strict clients.
"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:
- Emit
sessionCapabilities.list as an object: "list": {} (or use the schema/Rust-SDK type for SessionListCapabilities instead of a raw boolean).
- Drop the non-schema
"load": true field from sessionCapabilities; loadSession: true at the top level already covers it.
- 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.
serve --acpinitializeresponse violates the ACP schema:sessionCapabilities.listis a boolean instead of an object — strict clients (JetBrains IDEA) fail to connectRepo target:
Hmbown/CodeWhaleEnvironment
codewhalenpm wrapper 0.9.12, native binarycodewhale0.9.12 (Linux x64)codewhale serve --acp(ACP v1 server over stdio, newline-delimited JSON-RPC 2.0)com.intellij.platform.acp,ml-llmAI Assistant), registered via~/.jetbrains/acp.json:{ "codewhale": { "command": "/home/lujc/.npm-global/bin/codewhale", "args": ["serve", "--acp"] } }Summary
Since 0.9.12, the
initializeresponse ofcodewhale serve --acpadvertises session capabilities as boolean literals:Per the ACP schema,
SessionCapabilities.listis typed asSessionListCapabilities | 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 (Kotlinagent-client-protocolmodel, kotlinx.serialization) — throw aJsonDecodingExceptionwhile 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
Actual behavior
The
initializeresponse 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:"list": true— must be aSessionListCapabilitiesobject ({}means "supported", absent/nullmeans "not supported"). This is the one that breaks strict clients."load": true— not a defined property ofSessionCapabilitiesin the current schema (session/loadsupport is advertised via the top-levelloadSessionboolean, which codewhale already sets correctly). Currently harmless for lenient clients, but should be removed.Client-side failure (JetBrains IDEA 2026.2,
idea.log)The client marks the failure
recoverable=falseand 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:
(or omit
listentirely ifsession/listis not supported).Reference: working agents, same client, same request
Both connect successfully in IDEA 2026.2:
kimi acp):"sessionCapabilities":{"list":{},"resume":{},"close":{},"delete":{},"fork":{},"additionalDirectories":{}}reasonix acp):"sessionCapabilities":{"list":{},"resume":{},"close":{},"delete":{}}Regression window
0.9.11;initialize/session/new/session/promptall succeeded, see alsocodewhale-acp-session-config-issue.mdfiled against 0.9.11).0.9.12(2026-09-07), every connection attempt fails at the handshake. So thesessionCapabilitiesadvertisement was introduced/changed in 0.9.12 with the wrong JSON shape.Suggested fix
In the
serve --acpinitialize handler:sessionCapabilities.listas an object:"list": {}(or use the schema/Rust-SDK type forSessionListCapabilitiesinstead of a raw boolean)."load": truefield fromsessionCapabilities;loadSession: trueat the top level already covers it.initializeresponse 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
Content-Length-headered framing only produces a-32700parse error line per header/body line.codewhale --version/ interactive use are unaffected.