wavetermdev/waveterm · error

must provide an appId to WriteAppSecretBindingsCommand

Error message

must provide an appId to WriteAppSecretBindingsCommand

What it means

WriteAppSecretBindingsCommand persists secret bindings for an app in the wave app store, but only if the request identifies the app. The server checks data.AppId and rejects empty values before calling waveappstore.WriteAppSecretBindings. This prevents writing bindings with no owning app.

Source

Thrown at pkg/wshrpc/wshserver/wshserver.go:1124

}

func (ws *WshServer) DeleteAppFileCommand(ctx context.Context, data wshrpc.CommandDeleteAppFileData) error {
	if data.AppId == "" {
		return fmt.Errorf("must provide an appId to DeleteAppFileCommand")
	}
	return waveappstore.DeleteAppFile(data.AppId, data.FileName)
}

func (ws *WshServer) RenameAppFileCommand(ctx context.Context, data wshrpc.CommandRenameAppFileData) error {
	if data.AppId == "" {
		return fmt.Errorf("must provide an appId to RenameAppFileCommand")
	}
	return waveappstore.RenameAppFile(data.AppId, data.FromFileName, data.ToFileName)
}

func (ws *WshServer) WriteAppSecretBindingsCommand(ctx context.Context, data wshrpc.CommandWriteAppSecretBindingsData) error {
	if data.AppId == "" {
		return fmt.Errorf("must provide an appId to WriteAppSecretBindingsCommand")
	}
	return waveappstore.WriteAppSecretBindings(data.AppId, data.Bindings)
}

func (ws *WshServer) DeleteBuilderCommand(ctx context.Context, builderId string) error {
	if builderId == "" {
		return fmt.Errorf("must provide a builderId to DeleteBuilderCommand")
	}
	buildercontroller.DeleteController(builderId)
	return nil
}

func (ws *WshServer) StartBuilderCommand(ctx context.Context, data wshrpc.CommandStartBuilderData) error {
	if data.BuilderId == "" {
		return fmt.Errorf("must provide a builderId to StartBuilderCommand")
	}
	bc := buildercontroller.GetOrCreateController(data.BuilderId)
	rtInfo := wstore.GetRTInfo(waveobj.MakeORef("builder", data.BuilderId))

View on GitHub (pinned to a4447c1563)

Solutions

  1. Set AppId in CommandWriteAppSecretBindingsData from the actual app's OID before the call
  2. Ensure the app creation flow completed and returned an appId before binding secrets
  3. Check any helper that resolves appId from context for silent empty returns

Example fix

// before
_, err := client.WriteAppSecretBindingsCommand(ctx, wshrpc.CommandWriteAppSecretBindingsData{Bindings: b})
// after
if appId == "" { return fmt.Errorf("no appId") }
_, err := client.WriteAppSecretBindingsCommand(ctx, wshrpc.CommandWriteAppSecretBindingsData{AppId: appId, Bindings: b})
Defensive patterns

Strategy: validation

Validate before calling

if data.AppId == "" {
    return fmt.Errorf("cannot write secret bindings: AppId is empty")
}
err := client.WriteAppSecretBindingsCommand(ctx, data)

Type guard

func hasAppId(data wshrpc.CommandWriteAppSecretBindingsData) bool {
    return data.AppId != ""
}

Try / catch

if err := client.WriteAppSecretBindingsCommand(ctx, data); err != nil {
    if strings.Contains(err.Error(), "must provide an appId") {
        // resolve appId from app context and retry
    }
    return err
}

Prevention

When it happens

Trigger: Invoking the WriteAppSecretBindings RPC with CommandWriteAppSecretBindingsData whose AppId is "" — typically because the caller never set it or derived it from an empty/failed lookup.

Common situations: UI flows where the app was deleted or not yet created before bindings were saved; hand-written wsh clients calling the RPC for automation; copying example code that left AppId blank.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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