paperclipai/paperclip · error · Error
ACPX runtime does not expose session goal controls
Error message
ACPX runtime does not expose session goal controls
What it means
The runtime host's controlGoal() delegates session goal set/pause/resume/clear to the underlying AcpxRuntimePort. This error is thrown when the wrapped runtime does not implement the optional controlGoal capability, so goal controls are unavailable for that runtime.
Source
Thrown at packages/paperclip-runner/src/drivers/acpx/runtime-host.ts:596
async status(): Promise<AcpxModelStatus> {
return structuredClone(await this.#runtime.getStatus());
}
goalCapability(): AcpxRuntimeGoalCapability | null {
return this.#runtime.goalCapability?.() ?? null;
}
goalSnapshot(): AcpxRuntimeGoalSnapshot | null {
return this.#runtime.goalSnapshot?.() ?? null;
}
async controlGoal(
action: "set" | "pause" | "resume" | "clear",
objective?: string,
): Promise<AcpxRuntimeGoalSnapshot | null> {
if (!this.#runtime.controlGoal) {
throw new Error("ACPX runtime does not expose session goal controls");
}
return await this.#runtime.controlGoal(action, objective);
}
startTurn(input: AcpxRuntimeTurnInput): AcpxRuntimeTurn {
if (this.#closed || this.#closingStarted) {
throw new Error("ACPX runtime host is closing");
}
if (this.#activeTurn) {
throw new Error("ACPX runtime host already has an active turn");
}
const requestId = boundedRequestId(input.requestId);
const text = boundedTurnText(input.text);
const turn = this.#runtime.startTurn({
text,
requestId,
...(input.signal ? { signal: input.signal } : {}),
...(input.onElicitation ? { onElicitation: input.onElicitation } : {}),View on GitHub (pinned to 01ad858492)
Solutions
- Check that the runtime implementation in use supports goal controls before calling controlGoal (feature-detect host's runtime port)
- Upgrade the ACPX runtime/adapter package to a version exposing controlGoal
- Skip goal-control UI/actions when the capability is absent
- If injecting a custom AcpxRuntimePort (e.g. in tests), implement controlGoal
Example fix
// before
await host.controlGoal("set", objective);
// after
if (host.supportsGoalControls?.()) {
await host.controlGoal("set", objective);
} Defensive patterns
Strategy: validation
Validate before calling
if (typeof host.controlGoal !== "function") {
// goal controls unavailable; skip
} Type guard
function supportsGoalControls(runtime) {
return typeof (runtime as AcpxRuntimePort).controlGoal === "function";
} Try / catch
try {
await host.controlGoal("set", objective);
} catch (err) {
if (err.message.includes("session goal controls")) {
return null; // capability absent
}
throw err;
} Prevention
- Feature-detect goal-control support before surfacing goal UI
- Keep runtime/adapter packages on versions that implement controlGoal
- Avoid test double runtimes that omit optional capabilities you exercise
- Gate goal actions behind a capability flag per runtime build
When it happens
Trigger: Calling host.controlGoal("set"|"pause"|"resume"|"clear") when the underlying runtime instance was created without goal-control support, i.e. this.#runtime.controlGoal is undefined.
Common situations: Using an older or minimal ACPX runtime implementation that predates goal controls; a test/dummy runtime port that omits controlGoal; feature-flagged runtime builds where goal support is disabled.
Related errors
- ACPX session goal action ${action} is unavailable
- Verified ACPX installation does not match its profile
- ACPX runtime host is closing
- ACPX runtime host already has an active turn
- Sandbox driver does not support duplex channels for this lea
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/ed32830bdb96cbd3.
Report an issue: GitHub.