wavetermdev/waveterm · critical

error creating client: %w

Error message

error creating client: %w

What it means

EnsureInitialData looks up the Client singleton; when it returns wstore.ErrNotFound, the code creates the client. This error wraps any failure of CreateClient itself — meaning first-launch client initialization could not be persisted.

Source

Thrown at pkg/wcore/wcore.go:41

	"github.com/wavetermdev/waveterm/pkg/wcloud"
	"github.com/wavetermdev/waveterm/pkg/wps"
	"github.com/wavetermdev/waveterm/pkg/wstore"
)

// the wcore package coordinates actions across the storage layer
// orchestrating the wave object store, the wave pubsub system, and the wave rpc system

// Ensures that the initial data is present in the store, creates an initial window if needed
func EnsureInitialData() (bool, error) {
	// does not need to run in a transaction since it is called on startup
	ctx, cancelFn := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancelFn()
	client, err := wstore.DBGetSingleton[*waveobj.Client](ctx)
	firstLaunch := false
	if err == wstore.ErrNotFound {
		client, err = CreateClient(ctx)
		if err != nil {
			return false, fmt.Errorf("error creating client: %w", err)
		}
		firstLaunch = true
	}
	if client.TempOID == "" {
		log.Println("client.TempOID is empty")
		client.TempOID = uuid.NewString()
		err = wstore.DBUpdate(ctx, client)
		if err != nil {
			return firstLaunch, fmt.Errorf("error updating client: %w", err)
		}
	}
	if client.InstallId == "" {
		log.Println("client.InstallId is empty")
		client.InstallId = uuid.NewString()
		err = wstore.DBUpdate(ctx, client)
		if err != nil {
			return firstLaunch, fmt.Errorf("error updating client: %w", err)
		}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Inspect the wrapped error from CreateClient for the storage-level cause
  2. Check write permissions and free space in the wave data directory (~/.waveterm)
  3. Delete/restore a corrupted wave store so a clean first launch can recreate the client
  4. Ensure only one instance initializes the store concurrently (lock contention can fail creation)

Example fix

// before
if err == wstore.ErrNotFound {
    client, err = wcore.CreateClient(ctx)
    if err != nil { return false, fmt.Errorf("error creating client: %w", err) }
}
// after
if err == wstore.ErrNotFound {
    if err := ensureStoreWritable(); err != nil { return false, err }
    client, err = wcore.CreateClient(ctx)
    if err != nil { return false, fmt.Errorf("error creating client: %w", err) }
}
Defensive patterns

Strategy: try-catch

Validate before calling

if err == wstore.ErrNotFound {
    if fi, statErr := os.Stat(dataDir); statErr != nil || !isWritableDir(dataDir) {
        return false, fmt.Errorf("wave data dir not writable: %v", statErr)
    }
}

Try / catch

_, err := wstore.DBGetSingleton[*waveobj.Client](ctx)
if errors.Is(err, wstore.ErrNotFound) {
    if _, cerr := wcore.CreateClient(ctx); cerr != nil {
        if strings.Contains(cerr.Error(), "error creating client") {
            // check data dir writability, disk space, single-instance lock
        }
    }
}

Prevention

When it happens

Trigger: wstore.DBGetSingleton returns ErrNotFound (first launch) and the subsequent CreateClient call fails: DB write error, disk full/permissions, or another non-NotFound DB failure inside CreateClient.

Common situations: First run on a machine with a read-only or full data directory; corrupted store preventing singleton creation; crash mid-initialization leaving partial data.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/c4aa4a41e246fd46. Report an issue: GitHub.