sipeed/picoclaw · error

failed to write response_format field: %w

Error message

failed to write response_format field: %w

What it means

Thrown when writer.WriteField("response_format", "json") fails in WhisperTranscriber's multipart builder. The value is the compile-time constant "json", so no input can make the field itself invalid; only a bytes.Buffer write/allocation failure under memory exhaustion triggers it. Companion of 315 one line later.

Source

Thrown at pkg/audio/asr/whisper_transcriber.go:122

	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,
		"model":      t.modelID,
		"provider":   t.providerName,
	})

	audioFile, err := os.Open(audioFilePath)

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Same remediation as 315: bound input size, raise limits, pre-grow the buffer.
Defensive patterns

Strategy: try-catch

Validate before calling

if len(data) > maxInMemoryAudio { return errors.New("audio too large for in-memory multipart build") }

Try / catch

if _, err := whisper.TranscribeWithData(ctx, data, name); err != nil {
    // Constant field write failed: memory exhaustion; same handling as 314/315.
    return err
}

Prevention

When it happens

Trigger: Memory allocation failure during multipart buffering of a large audio payload.

Common situations: Same memory-pressure profile as 314/315.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/2adc86a2dc2b5433. Report an issue: GitHub.