homebridge/homebridge · warning

Failed to save commissioning info to disk: ${errorMessage}

Error message

Failed to save commissioning info to disk: ${errorMessage}

What it means

CommissioningManager.generateCommissioningInfo writes a commissioning JSON file (passcode, discriminator, commissioned state) to disk so tools like config-ui-x can show pairing info. If writeFile fails the pairing data is still printed to the log; only the on-disk file is missing.

Source

Thrown at src/matter/server/CommissioningManager.ts:278

    // Save commissioning info to disk for UI access
    try {
      if (!deps.matterStoragePath) {
        throw new Error('Matter storage path not initialized')
      }
      const commissioningFilePath = join(deps.matterStoragePath, 'commissioning.json')
      const commissioningData = {
        qrCode: qrCodePayload,
        manualPairingCode,
        serialNumber: deps.serialNumber,
        passcode: this.passcode,
        discriminator: this.discriminator,
        commissioned: deps.fabricManager.isCommissioned(),
      }
      await writeFile(commissioningFilePath, JSON.stringify(commissioningData, null, 2), 'utf-8')
      log.debug(`Saved commissioning info to ${commissioningFilePath}`)
    } catch (error: unknown) {
      const errorMessage = error instanceof Error ? error.message : String(error)
      log.warn(`Failed to save commissioning info to disk: ${errorMessage}`)
    }

    // Display commissioning information
    log.info(`${'='.repeat(60)}`)
    log.info('📱 MATTER COMMISSIONING INFORMATION')
    log.info('='.repeat(60))
    log.info(`Manual Pairing Code: ${manualPairingCode}`)
    log.info(`Passcode: ${passcode}`)
    log.info(`Discriminator: ${discriminator}`)
    log.info('QR Code for commissioning:')

    // Generate and display QR code in terminal using matter.js native QR renderer
    const qrCodeString = QrCode.get(qrCodePayload)
    log.info(`\n${qrCodeString}`)

    log.info(`${'='.repeat(60)}`)
  }

View on GitHub (pinned to edf5493034)

Solutions

  1. Check the commissioning/persist directory exists and is writable by the Homebridge user
  2. Free disk space / fix filesystem errors
  3. Verify the -U storage path is a valid writable directory
  4. Fix file ownership after restoring backups (chown to the service user)

Example fix

// before
# storage dir owned by root
sudo chown -R homebridge:homebridge /var/lib/homebridge && hb-service restart
// after
# commissioning file writes succeed on next pairing
Defensive patterns

Strategy: validation

Validate before calling

import { accessSync, constants, mkdirSync } from 'node:fs'
mkdirSync(path.dirname(commissioningFilePath), { recursive: true })
accessSync(path.dirname(commissioningFilePath), constants.W_OK)

Try / catch

try {
  await writeFile(commissioningFilePath, JSON.stringify(data, null, 2), 'utf-8')
} catch (error) {
  logger.warn('Failed to save commissioning info to disk:', error instanceof Error ? error.message : error)
}

Prevention

When it happens

Trigger: generateCommissioningInfo calls writeFile(commissioningFilePath, ...) and it throws — unwritable storage dir, permission denied, ENOSPC, path invalid after custom -U storage path, or JSON serialization issue.

Common situations: Docker containers with read-only or mis-owned persist directories; disk full; migrating storage with -U pointing at a nonexistent directory; running Homebridge as a different user after hb-service changes.

Related errors


AI-assisted analysis of homebridge/homebridge@edf5493034 (2026-08-30). Data as JSON: /api/errors/8fdb4b19eced36d7. Report an issue: GitHub.