slopus/happy · warning

Claude goal action is not ready: remote mode is not active

Error message

Claude goal action is not ready: remote mode is not active

What it means

Goal actions are only applied while the CLI runs Claude in remote mode (currentRunMode === 'remote'), where results can be observed and synced. If the action arrives while in another run mode (e.g. local/interactive or transitioning), the handler rejects it as not ready.

Source

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

        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');
        }
        if (!currentSession || currentSession.thinking) {
            throw new Error('Claude goal action is not ready while Claude is thinking');
        }
        if (messageQueue.size() > 0) {
            throw new Error('Claude message queue is busy');
        }

        const slashCommand = command.type === 'clear'
            ? '/goal clear'
            : `/goal ${command.objective}`;
        const mode = currentEnhancedMode();

        return await new Promise<{ ok: true }>((resolve, reject) => {
            const timeout = setTimeout(() => {
                pendingClaudeGoalAction = null;
                reject(new Error('Timed out waiting for Claude goal confirmation'));
            }, 30000);

View on GitHub (pinned to b824cd0a46)

Solutions

  1. Retry the goal action once the session is fully in remote mode.
  2. Wait for session initialization/mode transition to complete before acting.
  3. Avoid toggling local/remote modes while issuing goal actions.
  4. Update the app to disable goal actions until the session reports remote mode.

Example fix

// before
await rpc('goal-action', { action: 'set', goal: 'x' }); // during mode switch
// after
if (session.runMode === 'remote') await rpc('goal-action', { action: 'set', goal: 'x' });
Defensive patterns

Strategy: retry

Validate before calling

if (session.runMode !== 'remote') {
  console.warn('Goal actions require remote mode — retry after the session finishes switching');
  return;
}

Type guard

function isRemoteMode(m: string | null | undefined): m is 'remote' {
  return m === 'remote';
}

Try / catch

async function goalActionWhenRemote(p: unknown, tries = 5) {
  for (let i = 0; i < tries; i++) {
    try { return await rpc('goal-action', p); }
    catch (err) {
      if (!(err as Error).message.includes('remote mode is not active') || i === tries - 1) throw err;
      await sleep(2000);
    }
  }
}

Prevention

When it happens

Trigger: A 'goal-action' RPC arrives while currentRunMode is not 'remote' — e.g. during mode handoff, in local/interactive mode, or before the mode state machine has settled into remote.

Common situations: Sending a goal action right as the user switches between local and remote mode; mobile app acting on a session still initializing; RPC racing the mode transition after reconnection.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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