paperclipai/paperclip · error
session.goal.set requires an objective or active/paused stat
Error message
session.goal.set requires an objective or active/paused status
What it means
The session.goal.set command needs enough information to derive an action: either a non-empty objective ('set') or a status of 'paused' ('pause') or 'active' ('resume'). The sidecar parses these fields and throws when it cannot map them to any action.
Source
Thrown at packages/paperclip-runner/src/cli/acpx-runtime-sidecar.ts:464
if (request.command === "session.goal.get") {
const activeHost = requireHost();
return observedGoalProjection(activeHost.goalCapability(), activeHost.goalSnapshot(), turnId !== null);
}
if (request.command === "session.goal.set") {
const activeHost = requireHost();
if (Object.prototype.hasOwnProperty.call(request.params, "tokenBudget")) {
throw new Error("The negotiated ACP goal extension does not support token budget control");
}
const objective = text(request.params.objective).trim();
const status = text(request.params.status).trim();
const action = objective
? "set"
: status === "paused"
? "pause"
: status === "active"
? "resume"
: null;
if (!action) throw new Error("session.goal.set requires an objective or active/paused status");
const goal = await activeHost.controlGoal(action, objective || undefined);
return observedGoalProjection(activeHost.goalCapability(), goal, turnId !== null);
}
if (request.command === "session.goal.clear") {
const activeHost = requireHost();
await activeHost.controlGoal("clear");
return observedGoalProjection(activeHost.goalCapability(), null, turnId !== null);
}
if (request.command === "session.suspend") {
if (turnId || tools.size > 0 || inputs.size > 0) {
throw new Error("ACPX session is not at a safe suspension point");
}
// Cleanup retries must be able to reach the retained host. The command is
// still serialized, and retainActiveHostCleanup keeps admission closed
// until one sequential close proves ownership was released.
const activeHost = requireHost({ allowCleanupRetry: true });
const identity = acpxProviderSessionIdentity(
activeHost.identity(),View on GitHub (pinned to 01ad858492)
Solutions
- Pass a non-empty objective string in params.objective
- Or pass params.status as exactly 'active' or 'paused'
- Normalize the caller's status enum to the ACP vocabulary before dispatch
Example fix
// before
host.dispatch({ command: 'session.goal.set', params: { status: 'running' } });
// after
host.dispatch({ command: 'session.goal.set', params: { status: 'active' } }); Defensive patterns
Strategy: validation
Validate before calling
function canDispatchGoalSet(p) { return Boolean((p.objective ?? '').trim()) || ['active','paused'].includes(p.status); }
if (!canDispatchGoalSet(params)) throw new Error('goal.set needs objective or active/paused status'); Type guard
function isValidGoalSetParams(p: { objective?: string; status?: string }): boolean {
return Boolean(p.objective?.trim()) || p.status === 'active' || p.status === 'paused';
} Try / catch
try { await host.dispatch({ command: 'session.goal.set', params }); }
catch (e) { if (String(e.message).includes('requires an objective')) { /* prompt user for objective or correct status */ } else throw e; } Prevention
- Map your app's status enum to the ACP vocabulary ('active'/'paused') at the boundary
- Trim and check objective before dispatching
- Only call goal.set when there is something to set; use goal.clear otherwise
When it happens
Trigger: Dispatching session.goal.set where params.objective is empty/whitespace and params.status is not exactly 'paused' or 'active' (e.g. empty, 'running', 'stop').
Common situations: Passing status values from an app-level enum that doesn't match the ACP vocabulary; calling goal.set with only a token budget (also rejected) or blank fields after trimming.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Invalid status '${String(rawStatus)}'. Must be one of: ${PLU
- "tool" is required and must be a string
- "runContext" is required and must be an object
- "runContext" must include agentId, runId, companyId, and pro
- ${prefix}: the capability must be an object.
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/8123b361cd8aa4c2.
Report an issue: GitHub.