zylon-ai/private-gpt · error · ValueError

Audio size {audio_size} exceeds maximum allowed size of {set

Error message

Audio size {audio_size} exceeds maximum allowed size of {settings().chat.maximum_blob_size} bytes.

What it means

Raised by POST /skills/{skill_id}/versions when SkillService.create_version() returns None — meaning the skill disappeared between the initial existence check and the actual version write (or the service otherwise could not resolve it). It is a second, service-level not-found guard after form parsing and file storage have already run.

Source

Thrown at private_gpt/chat/input_models.py:920

                image_size = len(image_bytes.read())
                if image_size > settings().chat.maximum_blob_size:
                    raise ValueError(
                        f"Image size {image_size} exceeds maximum "
                        f"allowed size of {settings().chat.maximum_blob_size} bytes."
                    )

                image_bytes.seek(0)
                blocks.append(
                    LIImageBlock(
                        image=image_bytes.read(),
                        image_mimetype=block.source.get_media_type(),
                    )
                )
            elif isinstance(block, AudioBlock):
                audio_bytes = load_file_from_uri(block.source.get_data())
                audio_size = len(audio_bytes.read())
                if audio_size > settings().chat.maximum_blob_size:
                    raise ValueError(
                        f"Audio size {audio_size} exceeds maximum "
                        f"allowed size of {settings().chat.maximum_blob_size} bytes."
                    )
                audio_bytes.seek(0)
                blocks.append(
                    LIAudioBlock(
                        audio=audio_bytes.read(),
                        format=block.source.get_media_type(),
                    )
                )
            elif isinstance(block, ContentBlockType):
                if block.type not in custom_blocks:
                    custom_blocks[block.type] = []
                custom_blocks[block.type].append(block)

        return blocks if blocks else None, custom_blocks if custom_blocks else None

    def _convert_message(self) -> list[ChatMessage]:

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Retry once: re-check existence, then re-submit the version if the skill is still present.
  2. Serialize skill mutations per skill id in the client to avoid delete/version races.
  3. If consistently reproducible, verify the service's storage for the skill id is intact.

Example fix

// before
await skillsApi.createVersion(id, col, files); // may 404 mid-flight

// after
try { await skillsApi.createVersion(id, col, files); }
catch (e) {
  if (e.status === 404 && (await skillsApi.get(id, col).catch(() => null))) {
    return skillsApi.createVersion(id, col, files); // retry once
  }
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

const stillThere = await skillsApi.get(id, collection).catch(() => null);
if (!stillThere) throw new SkillGoneError(id);

Try / catch

try { return await skillsApi.createVersion(id, collection, files); }
catch (e) {
  if (e.status === 404 && (await skillsApi.get(id, collection).catch(() => null))) {
    return skillsApi.createVersion(id, collection, files); // transient race: retry once
  }
  throw e;
}

Prevention

When it happens

Trigger: The skill is deleted concurrently while the multipart upload/version creation is in progress; service-layer lookup failing under the same race.

Common situations: Two actors operating on the same skill (one deleting, one versioning); long uploads widening the race window.

Related errors


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/34e8c889800ad7a3. Report an issue: GitHub.