{"record":{"id":"903da186031ac7da","repo":"sipeed/picoclaw","slug":"failed-to-copy-file-content-w","errorCode":null,"errorMessage":"failed to copy file content: %w","messagePattern":"failed to copy file content: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/audio/asr/elevenlabs_transcriber.go","lineNumber":79,"sourceCode":"\t}\n\n\tlogger.DebugCF(\"voice\", \"Audio file details\", map[string]any{\n\t\t\"size_bytes\": fileInfo.Size(),\n\t\t\"file_name\":  filepath.Base(audioFilePath),\n\t})\n\n\tvar requestBody bytes.Buffer\n\twriter := multipart.NewWriter(&requestBody)\n\n\tpart, err := writer.CreateFormFile(\"file\", filepath.Base(audioFilePath))\n\tif err != nil {\n\t\tlogger.ErrorCF(\"voice\", \"Failed to create form file\", map[string]any{\"error\": err})\n\t\treturn nil, fmt.Errorf(\"failed to create form file: %w\", err)\n\t}\n\n\tif _, err = io.Copy(part, audioFile); err != nil {\n\t\tlogger.ErrorCF(\"voice\", \"Failed to copy file content\", map[string]any{\"error\": err})\n\t\treturn nil, fmt.Errorf(\"failed to copy file content: %w\", err)\n\t}\n\n\tif err = writer.WriteField(\"model_id\", t.modelID); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to write model_id field: %w\", err)\n\t}\n\n\tif err = writer.Close(); err != nil {\n\t\tlogger.ErrorCF(\"voice\", \"Failed to close multipart writer\", map[string]any{\"error\": err})\n\t\treturn nil, fmt.Errorf(\"failed to close multipart writer: %w\", err)\n\t}\n\n\turl := t.apiBase + \"/v1/speech-to-text\"\n\treq, err := http.NewRequestWithContext(ctx, \"POST\", url, &requestBody)\n\tif err != nil {\n\t\tlogger.ErrorCF(\"voice\", \"Failed to create request\", map[string]any{\"error\": err})\n\t\treturn nil, fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/audio/asr/elevenlabs_transcriber.go#L61-L97","documentation":"Thrown when io.Copy(part, audioFile) fails while streaming the opened audio file into the multipart buffer in ElevenLabsTranscriber.Transcribe. This is a read error on the file descriptor mid-copy (the multipart side is an in-memory buffer that does not fail under normal conditions). The wrapped error is usually a *os.PathError with Op 'read'.","triggerScenarios":"The file is truncated or deleted-and-recreated while being read; EIO from a failing disk or stale NFS handle; the file is a named pipe or device whose writer closes early.","commonSituations":"Recorder still writing the file when transcription starts (partial file, then rewrite); audio captured on a network mount that drops mid-copy; path actually points at a FIFO.","solutions":["Make sure the recording is fully written and closed before Transcribe is called (write to temp name, rename atomically).","If reading from a mount, copy the file locally first (os.ReadFile then transcribe from a temp file).","Check dmesg/system logs for disk errors if EIO recurs."],"exampleFix":"// before: transcribe while recorder may still write\nresp, err := t.Transcribe(ctx, livePath)\n\n// after: atomic handoff via rename\ntmp := livePath + \".part\"\n// recorder writes and closes tmp, then:\nif err := os.Rename(tmp, livePath); err != nil { return err }\nresp, err := t.Transcribe(ctx, livePath)","handlingStrategy":"try-catch","validationCode":"// Ensure the file is fully written and stable before transcription:\nfi, err := os.Stat(path)\nif err != nil { return err }\nif fi.Size() == 0 { return errors.New(\"audio still being written\") }","typeGuard":"func isReadErr(err error) bool {\n    var pe *os.PathError\n    return errors.As(err, &pe) && pe.Op == \"read\"\n}","tryCatchPattern":"resp, err := el.Transcribe(ctx, path)\nif err != nil {\n    if isReadErr(err) {\n        // mid-copy I/O failure: verify the file then retry once\n        if _, serr := os.Stat(path); serr == nil {\n            resp, err = el.Transcribe(ctx, path)\n        }\n    }\n    if err != nil { return err }\n}","preventionTips":["Recorders: write to file.part, fsync, then os.Rename to the final name.","Avoid transcribing FIFOs/devices; only regular files.","Check disk health when EIO appears in logs."],"tags":["filesystem","io","elevenlabs","audio","go"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}