Skip to content

SQLSTATE[22003] / units column overflow during Whisper transcription #394

Description

@SoleroTG

Which version of integration_openai are you using?

4.5.1

Which version of Nextcloud are you using?

v33.0.6

Which browser are you using? In case you are using the phone App, specify the Android or iOS version and device please.

Firefox Ubuntu Snap 152.0.1

Describe the Bug

During audio transcription using a local Whisper backend (such as LocalAI), the background job (cron.php) crashes and discards the transcription result.

In nextcloud.log, the following two error logs are visible:

  1. Could not create quota usage for user: test and quota type: 2. Error: An exception occurred while executing a query: SQLSTATE[22003]: Numeric value out of range: 1264 Out of range value for column 'units' at row 1
  2. Can not summarize call recording as no TextToTextSummary task provider is available (This secondary warning is raised because the transcription fails/crashes before completion, and/or llm_provider_enabled is set to 0).

Root Cause Analysis

  1. Numeric Overflow via Whisper Hallucination / Silence
    In lib/Service/OpenAiAPIService.php, the audio duration is calculated by fetching the end timestamp of the last segment in the response:
if (isset($response['segments'])) {
    $audioDuration = intval(round(floatval(array_pop($response['segments'])['end'])));
}

When local backends encounter silence or audio artifacts, they can loop and produce extremely high timestamps or return inf / nan.

  • intval(INF) on a 64-bit PHP environment evaluates to PHP_INT_MAX (9223372036854775807).
  • The database column units in the oc_openai_quota_usage table is defined as INT (signed 32-bit integer, max value 2147483647) via Version010100Date20231008173034.php.
  • Inserting PHP_INT_MAX into this column triggers a SQLSTATE[22003] numeric value out of range database error.
  1. Broken Exception Handling
    The insertion is wrapped in a try-catch block:
try {
    $this->createQuotaUsage($userId ?? '', Application::QUOTA_TYPE_TRANSCRIPTION, $audioDuration);
} catch (DBException $e) {
    ...
}

This block fails to catch the database exception because:

  • Casing mismatch: DBException is imported as use OCP\Db\Exception as DBException; with a lowercase b, while the Nextcloud Core class namespace is OCP\DB\Exception.
  • Class mismatch: When the QueryBuilder fails during executeStatement(), it throws a Doctrine-level exception (\Doctrine\DBAL\Exception\DriverException), which does not inherit from \OCP\DB\Exception.
  • The exception goes uncaught, causing the background job to crash, and the finished transcript is lost.

Note: This unsafe catch (DBException $e) pattern is present in 6 locations inside OpenAiAPIService.php (lines 506, 575, 608, 941, 983, 1065).

Expected Behavior

  1. Sanitize $audioDuration: The calculated audio duration should be sanitized to ensure it is finite and fits within a signed 32-bit integer.
  2. Robust Exception Catching: Database logging failures must never crash the main application/transcription flow. The service should catch generic \Throwable instead of DBException.

To Reproduce

  1. Configure Nextcloud with the integration_openai app using a local Whisper backend (like LocalAI).
  2. Trigger the transcription of an audio file containing background noise/silence which causes the Whisper backend to hallucinate high segment end timestamps.
  3. Run php cron.php or wait for the background job to process the transcription.
  4. The cron job will crash with the SQLSTATE[22003] error, and the transcript will be lost.

Suggested Fixes

  1. Limit $audioDuration bounds in OpenAiAPIService.php:
if (!is_finite($audioDuration) || $audioDuration < 0 || $audioDuration > 2147483647) {
    $audioDuration = 0; 
}
  1. Catch \Throwable in all 6 quota logging locations inside OpenAiAPIService.php:
try {
    $this->createQuotaUsage(...);
} catch (\Throwable $e) {
    $this->logger->warning('Could not create quota usage: ' . $e->getMessage());
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions