slopus/happy · error

Unsupported Claude goal action

Error message

Unsupported Claude goal action

What it means

The 'goal-action' RPC handler parses incoming params with parseClaudeGoalActionParams; if params are not a plain object or the parse yields no valid command, the handler rejects with this error. It exists to guard the goal-set/clear RPC surface against malformed remote requests from the mobile app.

Source

Thrown at packages/happy-cli/src/claude/runClaude.ts:578

        // which the SDK reads as "use Claude's own configuration". Coercing it
        // would pin every unset session to prompting mode.
        permissionMode: currentPermissionMode,
        model: currentModel,
        fallbackModel: currentFallbackModel,
        customSystemPrompt: currentCustomSystemPrompt,
        appendSystemPrompt: currentAppendSystemPrompt,
        allowedTools: currentAllowedTools,
        disallowedTools: currentDisallowedTools,
        effort: currentEffort,
    });

    session.rpcHandlerManager.registerHandler('goal-action', async (params: unknown) => {
        const actionParams = params && typeof params === 'object' && !Array.isArray(params)
            ? params as Record<string, unknown>
            : null;
        const command = actionParams ? parseClaudeGoalActionParams(actionParams) : null;
        if (!command) {
            throw new Error('Unsupported Claude goal action');
        }
        if (pendingClaudeGoalAction) {
            throw new Error('Claude goal action already in progress');
        }
        if (!latestClaudeGoalStatus || latestClaudeGoalStatus.status !== 'active') {
            throw new Error('No active Claude goal');
        }

        const capabilities = latestClaudeGoalStatus.capabilities ?? {};
        if (command.type === 'clear' && !capabilities.clear) {
            throw new Error('Claude clear goal action is not supported');
        }
        if (command.type === 'set' && !capabilities.edit) {
            throw new Error('Claude edit goal action is not supported');
        }
        if (currentRunMode !== 'remote') {
            throw new Error('Claude goal action is not ready: remote mode is not active');
        }

View on GitHub (pinned to b824cd0a46)

Solutions

  1. Update the CLI and mobile app to matching versions so both speak the same goal-action schema.
  2. Inspect the RPC params in debug logs and fix the payload shape (must be a plain object the parser accepts).
  3. Retry the action from the mobile app.
  4. If you control the sender, validate against the same schema parseClaudeGoalActionParams uses before sending.

Example fix

// before
send({ type: 'goal-action', params: 'clear' });
// after
send({ type: 'goal-action', params: { action: 'clear' } });
Defensive patterns

Strategy: type-guard

Validate before calling

const isPlainObject = (v: unknown): v is Record<string, unknown> =>
  typeof v === 'object' && v !== null && !Array.isArray(v);
if (!isPlainObject(params) || !('action' in params)) throw new Error('goal-action params must be an object with an action field');

Type guard

function isGoalActionParams(p: unknown): p is { action: 'set' | 'clear'; goal?: string } {
  if (typeof p !== 'object' || p === null || Array.isArray(p)) return false;
  const o = p as Record<string, unknown>;
  return (o.action === 'clear' || (o.action === 'set' && typeof o.goal === 'string'));
}

Try / catch

try {
  await rpc('goal-action', params);
} catch (err) {
  if ((err as Error).message === 'Unsupported Claude goal action') {
    logger.warn('Goal action rejected: payload did not match the expected schema — check CLI/app versions');
  } else throw err;
}

Prevention

When it happens

Trigger: An RPC 'goal-action' request arrives whose params are null, an array, a primitive, or whose fields fail parseClaudeGoalActionParams validation (e.g. missing/invalid action type or goal text).

Common situations: A newer mobile app sending a goal action shape the CLI doesn't understand (version skew); corrupted RPC payloads over the socket; calling the RPC directly with hand-crafted params.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31). Data as JSON: /api/errors/dacf780962804a6e. Report an issue: GitHub.