nexu-io/open-design · error

workspace balance response is invalid for ${requestedWorkspa

Error message

workspace balance response is invalid for ${requestedWorkspaceId}

What it means

Thrown in the legacy fallback path of resolveVelaWorkspaceBillingProjection: the vela CLI reported workspace-snapshot as unsupported, the code fell back to workspace-balance, but parseWorkspaceWalletBalance() could not extract a valid balance for the requested workspace from the legacy JSON. This is a data/contract mismatch between the vela binary's output and the parser.

Source

Thrown at apps/daemon/src/integrations/vela-billing.ts:168

    if (
      !(error instanceof VelaWorkspaceBillingSnapshotUnsupportedError) &&
      !isWorkspaceBillingSnapshotUnsupported(error, '')
    ) {
      throw error;
    }
    const legacyStdout = await run([
      'workspace-balance',
      '--workspace-id',
      requestedWorkspaceId,
      '--format',
      'json',
    ]);
    const workspaceBalance = parseWorkspaceWalletBalance(
      legacyStdout,
      requestedWorkspaceId,
    );
    if (!workspaceBalance) {
      throw new Error(`workspace balance response is invalid for ${requestedWorkspaceId}`);
    }
    return {
      snapshot: null,
      workspaceBalance,
    };
  }
}

export interface BillingCheckoutOptions {
  /** Team workspace id whose subscription is being purchased. */
  workspaceId?: string;
  /** Vela team subscription plan id. */
  planId?: WorkspaceTeamBillingPlanId;
  /** Seats to purchase for the team subscription (>= 1). */
  seats?: number;
  /** Where Stripe returns the user after success / cancel. */
  successUrl?: string;
  cancelUrl?: string;

View on GitHub (pinned to 5be4028344)

Solutions

  1. Upgrade the vela binary so workspace-snapshot is supported (avoids the legacy fallback entirely).
  2. Inspect the raw workspace-balance stdout from the vela CLI and update parseWorkspaceWalletBalance if its contract changed.
  3. Confirm the requestedWorkspaceId is one the CLI actually recognises.

Example fix

// before
const workspaceBalance = parseWorkspaceWalletBalance(legacyStdout, requestedWorkspaceId);
if (!workspaceBalance) {
  throw new Error(`workspace balance response is invalid for ${requestedWorkspaceId}`);
}

// after (capture raw output for diagnosis before throwing)
const workspaceBalance = parseWorkspaceWalletBalance(legacyStdout, requestedWorkspaceId);
if (!workspaceBalance) {
  log.warn('vela workspace-balance parse failed', { requestedWorkspaceId, stdoutHead: legacyStdout.slice(0, 500) });
  throw new Error(`workspace balance response is invalid for ${requestedWorkspaceId}`);
}
Defensive patterns

Strategy: try-catch

Type guard

function isWorkspaceBalanceInvalidError(err: unknown): boolean {
  return err instanceof Error && err.message.startsWith('workspace balance response is invalid for ');
}

Try / catch

try {
  return await resolveVelaWorkspaceBillingProjection({ workspaceId });
} catch (err) {
  if (isWorkspaceBalanceInvalidError(err)) {
    // snapshot unsupported AND legacy parse failed — degrade billing UI
    return { snapshot: null, workspaceBalance: null };
  }
  throw err;
}

Prevention

When it happens

Trigger: workspace-snapshot unsupported → run(['workspace-balance', ...]) succeeds but the returned JSON does not contain the fields parseWorkspaceWalletBalance expects (workspaceId mismatch, missing balanceUsd, or a different envelope). Only happens for a non-empty requestedWorkspaceId after the snapshot fallback.

Common situations: Vela CLI version that returns a workspace-balance envelope the parser does not recognise; workspace id that exists for snapshot but the legacy route returns a different workspace or an error body; partial/truncated CLI output; vela binary behaving differently across OS/arch.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/c9993be3d0945d90. Report an issue: GitHub.