HeyPuter/puter · warning · HttpError

insufficient_funds

insufficient_funds

Error message

Insufficient credits

What it means

In the AWS Textract OCR path, the driver checks the user's credit balance against the per-page cost (OCR_COSTS['aws-textract:detect-document-text:page'] = 150,000 microcents = $0.15/page) before making the paid Textract API call. If the user cannot afford even one page, the call is blocked.

Solutions

  1. Top up the user's credit balance.
  2. Switch to the Mistral OCR provider if it has a lower per-page cost for the user's use case.
  3. Use test_mode: true for development/testing to bypass the credit check.

Example fix

// before — calling OCR without checking balance
const result = await driver.recognize({
  source: 'large-doc.pdf',
  provider: 'aws-textract',
});

// after — handle insufficient credits
try {
  const result = await driver.recognize({ source: 'doc.pdf', provider: 'aws-textract' });
} catch (e) {
  if (e.code === 'insufficient_funds') {
    // prompt user to top up; Textract costs $0.15/page
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check credits if metering is accessible
const costPerPage = 150000; // microcents for Textract
const balance = await meteringService.getUserBalance(actor);
if (balance < costPerPage) {
  throw new Error('Insufficient credits for Textract OCR ($0.15/page minimum)');
}

Try / catch

try {
  const result = await driver.recognize({ ...args, provider: 'aws-textract' });
} catch (e) {
  if (e.code === 'insufficient_funds') {
    // Prompt user to top up, or switch to a cheaper provider
    showTopUpDialog('Textract OCR requires $0.15/page');
  }
}

Prevention

When it happens

Trigger: The authenticated user's credit balance is below 150,000 microcents (the Textract per-page cost). The check happens before the Textract call, so no upstream cost is incurred.

Common situations: A free-tier user with no remaining credits; a user whose balance was depleted by prior OCR jobs; large document processing where the user didn't check their balance first.

Related errors


AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12). Data as JSON: /api/errors/5b43fce157c309f8. Report an issue: GitHub.

Appendix: source

Thrown at src/backend/drivers/ai-ocr/OCRDriver.ts:272

            credentials: {
                accessKeyId: this.#awsConfig!.accessKeyId!,
                secretAccessKey: this.#awsConfig!.secretAccessKey!,
            },
            region,
        });
        this.#textractClients[region] = client;
        return client;
    }

    async #textractRecognize(loaded: LoadedFile, actor: Actor) {
        const usageType = 'aws-textract:detect-document-text:page';
        const costPerPage = OCR_COSTS[usageType];
        const hasCredits = await this.services.metering.hasEnoughCredits(
            actor!,
            costPerPage,
        );
        if (!hasCredits)
            throw new HttpError(402, 'Insufficient credits', {
                legacyCode: 'insufficient_funds',
            });

        // Prefer S3 direct source if the file is FS-backed; fall back to raw bytes.
        const s3Info =
            loaded.fsEntry &&
            loaded.fsEntry.bucket &&
            loaded.fsEntry.bucketRegion
                ? {
                      bucket: loaded.fsEntry.bucket,
                      bucketRegion: loaded.fsEntry.bucketRegion,
                      key: loaded.fsEntry.uuid,
                  }
                : null;

        const tryRun = async (useS3: boolean) => {
            const region =
                s3Info && useS3

View on GitHub (pinned to 908ec23eda)