stablyai/orca · error · Error

Invalid local log tail subscription id

Error message

Invalid local log tail subscription id

What it means

Thrown by validateSubscriptionId when the local-log-tail subscription id is not a string, is empty, or exceeds 200 characters. The subscription id keys into tailWatches (a Map of active log tail watchers keyed by sender), so it must be a bounded, non-empty string to prevent map pollution and unbounded key growth.

Source

Thrown at src/main/ipc/local-log-tail.ts:45

  if (!subscription) {
    return
  }
  tailWatches.delete(key)
  subscription.watcher.close()
}

function closeSenderWatches(senderId: number): void {
  senderCleanupRegistered.delete(senderId)
  for (const [key, subscription] of tailWatches) {
    if (subscription.senderId === senderId) {
      closeWatch(key)
    }
  }
}

function validateSubscriptionId(value: unknown): string {
  if (typeof value !== 'string' || value.length === 0 || value.length > 200) {
    throw new Error('Invalid local log tail subscription id')
  }
  return value
}

function registerSenderCleanup(sender: WebContents): void {
  if (senderCleanupRegistered.has(sender.id)) {
    return
  }
  senderCleanupRegistered.add(sender.id)
  sender.once('destroyed', () => closeSenderWatches(sender.id))
}

export function registerLocalLogTailHandlers(store: Store): void {
  ipcMain.handle(
    'fs:readLocalLogTail',
    async (_event, args: LocalLogTailReadArgs): Promise<LocalLogTailReadResult> => {
      const filePath = await resolveAuthorizedPath(args.filePath, store)
      return readLocalLogTailRange(filePath, args.fromByteOffset, args.expectedIdentity)

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Generate a unique, bounded-length id (e.g. crypto.randomUUID()) for each subscription and pass it as a string.
  2. Unsubscribe using the same id when the tail is no longer needed, so the watch is closed in closeSenderWatches.
  3. Never reuse or omit the id; track active ids in renderer state.

Example fix

// before
await ipc.call('localLogTail:subscribe', { id: maybeId ?? '', path })

// after
const id = crypto.randomUUID()
await ipc.call('localLogTail:subscribe', { id, path })
Defensive patterns

Strategy: validation

Validate before calling

function validSubId(value: unknown): string {
  if (typeof value !== 'string' || value.length === 0 || value.length > 200) {
    throw new Error('Invalid subscription id')
  }
  return value
}

Type guard

function isSubscriptionId(value: unknown): value is string {
  return typeof value === 'string' && value.length > 0 && value.length <= 200
}

Prevention

When it happens

Trigger: Calling a local-log-tail IPC subscribe/unsubscribe method with a missing, empty, non-string, or >200-char id. Reusing stale subscription ids after the sender was destroyed, or generating ids without a length cap.

Common situations: Renderer generates a uuid per subscription but a code path sends undefined. A bug causes the same empty id to collide across subscriptions. An adversarial or corrupted payload supplies an oversized id.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/bb84cdbdc76c4470. Report an issue: GitHub.