jlcodes99/cockpit-tools · error

floatingCard.errors.stopInstanceBeforeSwitch

floatingCard.errors.stopInstanceBeforeSwitch

Error message

请先停止实例再切换账号

What it means

For the Grok platform specifically, switching accounts is only allowed when the running instance is the default one. If the instance context points at a non-default Grok instance that is currently running, the switch is rejected with 'floatingCard.errors.stopInstanceBeforeSwitch' ('请先停止实例再切换账号' — stop the instance before switching accounts).

Source

Thrown at src/pages/FloatingCardWindow.tsx:1274

  const handleSwitch = useCallback(async () => {
    if (!viewedAccount || switchingAccountId || isCurrentViewed) return;
    setSwitchingAccountId(viewedAccount.id);
    setErrorText(null);
    try {
      if (instanceContext) {
        const instanceStore = resolveInstanceStoreApi(selectedPlatform);
        if (!instanceStore) {
          throw new Error(t('common.shared.instances.unsupported.title', '暂不支持当前系统'));
        }
        const instances = await instanceStore.refreshInstances();
        const targetInstance = findInstanceById(instances, instanceContext.instanceId);
        const wasRunning = targetInstance?.running === true;
        if (
          selectedPlatform === 'grok' &&
          instanceContext.instanceId !== DEFAULT_INSTANCE_ID &&
          wasRunning
        ) {
          throw new Error(
            t(
              'floatingCard.errors.stopInstanceBeforeSwitch',
              '请先停止实例再切换账号',
            ),
          );
        }
        await instanceStore.updateInstance({
          instanceId: instanceContext.instanceId,
          bindAccountId: viewedAccount.id,
          followLocalAccount: instanceContext.instanceId === DEFAULT_INSTANCE_ID ? false : undefined,
        });
        if (wasRunning) {
          await instanceStore.startInstance(instanceContext.instanceId);
        }
        const nextContext = {
          ...instanceContext,
          boundAccountId: viewedAccount.id,
        };

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. Stop the running Grok instance, then retry the account switch.
  2. Switch back to the default instance before switching accounts.
  3. Catch the error in the UI and prompt the user with a 'stop instance' action before proceeding.
  4. Guard caller-side: refresh instances, check running state, and stop the instance programmatically first.

Example fix

// before
await switchAccount(nextAccountId);
// after
const instances = await getInstances();
const inst = findInstanceById(instances, instanceId);
if (platform === 'grok' && instanceId !== DEFAULT_INSTANCE_ID && inst?.running) {
  await stopInstance(instanceId);
}
await switchAccount(nextAccountId);
Defensive patterns

Strategy: validation

Validate before calling

const instances = await getInstances();
const target = findInstanceById(instances, instanceId);
const mustStop = platform === 'grok' &&
  instanceId !== DEFAULT_INSTANCE_ID &&
  target?.running === true;
if (mustStop) await stopInstance(instanceId); // before switching

Type guard

const isRunningNonDefault = (ctx: InstanceContext, list: Instance[]) => {
  const inst = findInstanceById(list, ctx.instanceId);
  return ctx.instanceId !== DEFAULT_INSTANCE_ID && inst?.running === true;
};

Try / catch

try {
  await switchAccount(nextAccountId);
} catch (e) {
  if (e.message.includes('stopInstanceBeforeSwitch')) {
    await promptStopInstance(instanceId);
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling switch-account from FloatingCardWindow while selectedPlatform === 'grok', instanceContext.instanceId !== DEFAULT_INSTANCE_ID, and the target instance's running === true (as determined by findInstanceById on refreshed instances).

Common situations: User launches a secondary Grok instance, leaves it running, then tries to swap accounts from the floating card; automations attempting account switches without first stopping running instances.


AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05). Data as JSON: /api/errors/3a6e7bde37388df5. Report an issue: GitHub.