decolua/9router · error

machineId is required

Error message

machineId is required

What it means

createApiKey generates API keys that embed the machine id (generateApiKeyWithMachine), so the key is bound to a specific installation. It refuses to run without a machineId, because a machine-less key would be unverifiable at request-validation time.

Source

Thrown at src/lib/db/repos/apiKeysRepo.js:29

    isActive: row.isActive === 1 || row.isActive === true,
    createdAt: row.createdAt,
  };
}

export async function getApiKeys() {
  const db = await getAdapter();
  const rows = db.all(`SELECT * FROM apiKeys ORDER BY createdAt ASC`);
  return rows.map(rowToKey);
}

export async function getApiKeyById(id) {
  const db = await getAdapter();
  const row = db.get(`SELECT * FROM apiKeys WHERE id = ?`, [id]);
  return rowToKey(row);
}

export async function createApiKey(name, machineId) {
  if (!machineId) throw new Error("machineId is required");
  const db = await getAdapter();
  const { generateApiKeyWithMachine } = await import("@/shared/utils/apiKey");
  const result = generateApiKeyWithMachine(machineId);
  const apiKey = {
    id: uuidv4(),
    name,
    key: result.key,
    machineId,
    isActive: true,
    createdAt: new Date().toISOString(),
  };
  db.run(
    `INSERT INTO apiKeys(id, key, name, machineId, isActive, createdAt) VALUES(?, ?, ?, ?, ?, ?)`,
    [apiKey.id, apiKey.key, apiKey.name, apiKey.machineId, 1, apiKey.createdAt]
  );
  return apiKey;
}

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Pass the machine id explicitly: createApiKey(name, await getMachineId()) using the app's machine-id helper.
  2. If machineId comes from a request body, validate it is a non-empty string before calling and return a 400 to the client otherwise.
  3. Ensure the machine id has been generated/initialized (start the app once so ~/.9router state exists) before creating keys programmatically.

Example fix

// before
const key = await createApiKey(name);
// after
const machineId = await getMachineId();
if (!machineId) throw new Error("machine not initialized");
const key = await createApiKey(name, machineId);
Defensive patterns

Strategy: validation

Validate before calling

if (typeof machineId !== "string" || machineId.length === 0) {
  throw new TypeError("createApiKey requires a non-empty machineId");
}
await createApiKey(name, machineId);

Type guard

function hasMachineId(x) {
  return typeof x === "string" && x.trim().length > 0;
}

Try / catch

try {
  return await createApiKey(name, machineId);
} catch (err) {
  if (err.message === "machineId is required") {
    throw new Error("Machine id not initialized — start the app once before creating API keys");
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling createApiKey(name) with one argument, or createApiKey(name, null/undefined/"") — typically from code that hasn't loaded the machine id yet or passes an unset env/config value.

Common situations: Bootstrap/setup scripts running before MACHINE_ID is initialized; API route handlers reading machineId from a request body the client didn't send; fresh installs where the machine-id file hasn't been created yet.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/2e7f5dd765a603c5. Report an issue: GitHub.