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.
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 runtime host already has an active turn
- ACPX runtime host is closing
- ACPX session goal action
- Verified ACPX installation does not match its profile
- ACPX profile requires exact model ; received
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-10).
Data as JSON: /api/errors/ed32830bdb96cbd3.
Report an issue: GitHub.
Appendix: source
Thrown at packages/paperclip-runner/src/drivers/acpx/runtime-host.ts:639
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);
// Bound caller input before adding the provider's assigned-skill command.
// The command is internal framing; it must not consume the envelope's
// allowance or cause an otherwise valid envelope to be truncated/rejected.
const text = claudeNativeSkillPrompt(
boundedTurnText(input.text), this.#claudeSkillNames,
);View on GitHub (pinned to 3f1d897a7c)