slopus/happy · error

No machine ID found in settings

Error message

No machine ID found in settings

What it means

runOpenClaw registers the machine with the Happy API using the machineId stored in happy's settings file. If readSettings() returns null or a settings object without machineId, there is no stable identity to register and it throws. This usually means happy's settings file is missing, corrupted, or was created before machine IDs were introduced.

Source

Thrown at packages/happy-cli/src/openclaw/runOpenClaw.ts:152

export async function runOpenClaw(opts: RunOpenClawOptions): Promise<void> {
  const verbose = opts.verbose === true;
  const sessionTag = randomUUID();
  connectionState.setBackend('openclaw');

  const gatewayConfig = resolveGatewayConfig(opts);
  const log = (msg: string) => {
    logger.debug(`[openclaw] ${msg}`);
    if (verbose) {
      console.log(`[openclaw] ${msg}`);
    }
  };

  log(`Gateway URL: ${gatewayConfig.url}`);

  const api = await ApiClient.create(opts.credentials);
  const settings = await readSettings();
  if (!settings?.machineId) {
    throw new Error('No machine ID found in settings');
  }

  await api.getOrCreateMachine({
    machineId: settings.machineId,
    metadata: initialMachineMetadata,
  });

  const { state, metadata } = createSessionMetadata({
    flavor: 'openclaw',
    machineId: settings.machineId,
    startedBy: opts.startedBy,
  });
  const response = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
  if (response) {
    log(`Happy Session ID: ${response.id}`);
  }

  let session: ApiSessionClient;

View on GitHub (pinned to b824cd0a46)

Solutions

  1. Run a normal happy command (e.g. `happy`) once so settings and machineId are generated
  2. Check the settings file for a machineId field and inspect file permissions
  3. If upgrading from an old version, re-authenticate (`happy auth`) to regenerate settings
  4. Ensure you run as the same user whose HOME contains the happy settings

Example fix

// before
await api.getOrCreateMachine({ machineId: settings?.machineId });
// after
const settings = await readSettings();
if (!settings?.machineId) {
  await runHappyOnceToInitializeSettings(); // regenerate ~/.happy/settings.json
}
await api.getOrCreateMachine({ machineId: settings.machineId });
Defensive patterns

Strategy: validation

Validate before calling

const settings = await readSettings();
if (!settings?.machineId) {
  // run `happy` once to regenerate ~/.happy/settings.json before runOpenClaw
}

Type guard

const hasMachineId = (s: { machineId?: string } | null): s is { machineId: string } =>
  typeof s?.machineId === 'string' && s.machineId.length > 0;

Try / catch

try {
  await runOpenClaw(opts);
} catch (err) {
  if (err.message === 'No machine ID found in settings') {
    await reinitializeSettings(); // e.g. `happy auth`
    await runOpenClaw(opts);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling runOpenClaw when `await readSettings()` returns null or settings.machineId is undefined — settings file absent, unreadable, or predating the machineId field.

Common situations: Fresh install where the daemon was never run to generate settings; manual deletion or corruption of ~/.happy/settings.json; upgrading from a very old happy version whose settings lacked machineId; running under a different HOME/user so the settings path differs.

Related errors


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