sipeed/picoclaw · error
failed to write model field: %w
Error message
failed to write model field: %w
What it means
Thrown when writer.WriteField("model", t.modelID) fails in WhisperTranscriber's multipart builder. WriteField appends a short constant-size field to an in-memory bytes.Buffer; failure means buffer allocation failure under memory exhaustion. Not input-dependent and not network-related.
Source
Thrown at pkg/audio/asr/whisper_transcriber.go:117
})
var requestBody bytes.Buffer
writer := multipart.NewWriter(&requestBody)
part, err := writer.CreateFormFile("file", filename)
if err != nil {
logger.ErrorCF("voice", "Failed to create whisper form file", map[string]any{"error": err})
return nil, fmt.Errorf("failed to create form file: %w", err)
}
if _, copyErr := io.Copy(part, bytes.NewReader(data)); copyErr != nil {
logger.ErrorCF("voice", "Failed to copy whisper file content", map[string]any{"error": copyErr})
return nil, fmt.Errorf("failed to copy file content: %w", copyErr)
}
if err = writer.WriteField("model", t.modelID); err != nil {
logger.ErrorCF("voice", "Failed to write whisper model field", map[string]any{"error": err})
return nil, fmt.Errorf("failed to write model field: %w", err)
}
if err = writer.WriteField("response_format", "json"); err != nil {
logger.ErrorCF("voice", "Failed to write whisper response_format field", map[string]any{"error": err})
return nil, fmt.Errorf("failed to write response_format field: %w", err)
}
if err = writer.Close(); err != nil {
logger.ErrorCF("voice", "Failed to close whisper multipart writer", map[string]any{"error": err})
return nil, fmt.Errorf("failed to close multipart writer: %w", err)
}
return t.doRequest(ctx, &requestBody, writer.FormDataContentType(), int64(len(data)))
}
func (t *WhisperTranscriber) Transcribe(ctx context.Context, audioFilePath string) (*TranscriptionResponse, error) {
logger.InfoCF("voice", "Starting whisper transcription", map[string]any{
"audio_file": audioFilePath,View on GitHub (pinned to 49183d7e8d)
Solutions
- Increase memory headroom or cap audio input size.
- Profile memory: the multipart body duplicates the audio in RAM.
Defensive patterns
Strategy: try-catch
Validate before calling
if len(data) > maxInMemoryAudio { return errors.New("audio too large; multipart build may exhaust memory") } Try / catch
if _, err := whisper.TranscribeWithData(ctx, data, name); err != nil {
// WriteField into bytes.Buffer: only OOM-class failures; shrink input or raise limits, do not blind-retry.
return err
} Prevention
- Cap input size at intake; alert on memory pressure near transcription calls.
- Keep a 2x-headroom rule between the memory limit and the largest accepted recording.
When it happens
Trigger: Severe memory pressure while a large audio payload is being buffered; otherwise unreachable.
Common situations: Memory-capped containers transcribing large files; same class as 306/314.
Related errors
- failed to copy file content: %w
- failed to write response_format field: %w
- failed to close multipart writer: %w
- failed to write model_id field: %w
- failed to close multipart writer: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/ecd4cc5f4c67cc80.
Report an issue: GitHub.