HeyPuter/puter · warning · HttpError
insufficient_funds
insufficient_funds
Error message
Insufficient credits for image generation
What it means
The Together image provider checks the user's credit balance via meteringService.hasEnoughCredits() before making the paid upstream API call. The estimated cost is computed from the model's pricing (per-image, per-tier, or per-megapixel). If the user's balance is insufficient, this error prevents the call to Together AI and avoids unbilled usage.
Source
Thrown at src/backend/drivers/ai-image/providers/together/TogetherImageProvider.ts:159
const centsPerMP = selectedModel.costs['1MP'];
if (centsPerMP === undefined) {
throw new Error(`Model ${selectedModel.id} missing '1MP' cost`);
}
const MP = (ratio.h * ratio.w) / 1_000_000;
costInMicroCents = centsPerMP * MP * 1_000_000;
usageAmount = MP;
usageKey = '1MP';
}
const usageType = `${selectedModel.id}:${usageKey}`;
const usageAllowed = await this.#meteringService.hasEnoughCredits(
actor,
costInMicroCents,
);
if (!usageAllowed) {
throw new HttpError(
402,
'Insufficient credits for image generation',
{ legacyCode: 'insufficient_funds' },
);
}
// Resolve abstract aspect ratios (e.g. 1:1, 16:9) to concrete pixel
// dimensions via the model's own resolution_map.
let resolvedRatio = ratio;
if (
pricingUnit === 'per-tier' &&
quality &&
selectedModel.resolution_map
) {
const ratioKey = `${ratio.w}:${ratio.h}`;
const resolutionEntry =
selectedModel.resolution_map[ratioKey]?.[quality];
if (resolutionEntry) {View on GitHub (pinned to 908ec23eda)
Solutions
- Top up the user's credit balance through the billing system.
- Use a lower-cost model or lower resolution tier to reduce the per-request cost.
- Check the user's balance via the metering API before attempting generation and display a top-up prompt.
- Use test_mode: true for development/testing to bypass the credit check.
Example fix
// before — calling without checking balance
const url = await provider.generate({ prompt: 'a cat', model: 'togetherai:expensive-model' });
// after — use test_mode for dev, or catch the 402
try {
const url = await provider.generate({ prompt: 'a cat', model: 'togetherai:black-forest-labs/FLUX.1-schnell' });
} catch (e) {
if (e.code === 'insufficient_funds') {
// prompt user to top up credits
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Check balance before generation if a metering client is available
const balance = await meteringService.getUserBalance(actor);
const estimatedCost = estimateTogetherCost(selectedModel, ratio, quality);
if (balance < estimatedCost) {
throw new Error('Insufficient credits — please top up your balance');
} Try / catch
try {
const url = await provider.generate(params);
} catch (e) {
if (e.legacyCode === 'insufficient_funds' || e.code === 'insufficient_funds') {
// Show top-up prompt to user
showTopUpDialog();
} else {
throw e;
}
} Prevention
- Check the user's credit balance via the metering API before attempting generation.
- Use test_mode: true in development to bypass the credit check.
- Choose lower-cost models or resolutions when credits are low.
When it happens
Trigger: The authenticated user's credit balance is lower than the computed costInMicroCents for the requested model and resolution. This is a per-request check; each generation call is gated independently.
Common situations: A free-tier user who has exhausted their credits; a user on a paid plan whose balance hasn't been topped up; calling a high-cost model (e.g. 2K or 4K resolution) with minimal remaining credits.
Related errors
AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12).
Data as JSON: /api/errors/fe5563fd48c9ea28.
Report an issue: GitHub.