moeru-ai/airi · error · Error

Server # {index} is missing an identifier.

Error message

Server # {index} is missing an identifier.

What it means

Thrown by buildConfigFile while iterating MCP server form rows: a row's identifier (after trim) is empty. The message is i18n-driven via translateMessage('errors.empty-identifier', { index }), so the literal text varies by locale; the English default reads 'Server #N is missing an identifier.'.

Source

Thrown at apps/stage-tamagotchi/src/renderer/pages/settings/modules/mcp-config.ts:96

  if (!server.enabled)
    config.enabled = false

  return config
}

/** Builds the persisted MCP config file from editable rows. */
export function buildConfigFile(
  servers: ServerForm[],
  translateMessage: TranslateMcpMessage,
): ElectronMcpStdioConfigFile {
  const config: ElectronMcpStdioConfigFile = { mcpServers: {} }
  const seenIdentifiers = new Set<string>()

  for (const [index, server] of servers.entries()) {
    const identifier = server.identifier.trim()
    if (!identifier)
      throw new Error(translateMessage('errors.empty-identifier', { index: index + 1 }))

    if (seenIdentifiers.has(identifier))
      throw new Error(translateMessage('errors.duplicate-identifier', { name: identifier }))

    if (!server.command.trim())
      throw new Error(translateMessage('errors.empty-command', { name: identifier }))

    seenIdentifiers.add(identifier)
    config.mcpServers[identifier] = buildServerConfig(server)
  }

  return config
}

/** Builds the JSON editor draft while preserving the current draft when form validation fails. */
export function syncJsonDraftFromServers(
  servers: ServerForm[],
  previousDraft: string,

View on GitHub (pinned to 27111382b4)

Solutions

  1. Fill in a unique identifier for every server row before saving.
  2. Disable the Save button until all rows have non-empty, unique identifiers.
  3. Remove empty rows from the form before buildConfigFile runs.
  4. Pre-trim and validate identifiers in the form's reactive state.
Defensive patterns

Strategy: validation

Validate before calling

function allServersHaveIdentifier(servers: ServerForm[]): boolean {
  return servers.every(s => s.identifier.trim().length > 0)
}

Type guard

function isNonEmptyIdentifier(id: string): boolean {
  return typeof id === 'string' && id.trim().length > 0
}

Try / catch

try {
  buildConfigFile(servers, t)
} catch (e) {
  // e.message is the i18n string; surface next to the offending row
}

Prevention

When it happens

Trigger: User added an MCP server row in settings but left the identifier/name field blank, then saved. Each row is validated in order; the first empty identifier aborts the build.

Common situations: Form validation gap — save enabled before identifier entered; JSON-draft sync created a row with empty identifier; user cleared a row's name to rename it and saved prematurely.

Related errors


AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12). Data as JSON: /api/errors/7c7bec3b75aa46dc. Report an issue: GitHub.