{"record":{"id":"888190c537c60a29","repo":"chenhg5/cc-connect","slug":"edge-tts-create-temp-file-w","errorCode":null,"errorMessage":"edge-tts: create temp file: %w","messagePattern":"edge-tts: create temp file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tts.go","lineNumber":688,"sourceCode":"\t\tvoice = \"zh-CN-XiaoxiaoNeural\" // default Chinese voice\n\t}\n\treturn &EdgeTTS{\n\t\tVoice: voice,\n\t}\n}\n\n// Synthesize uses edge-tts CLI to convert text to MP3 audio bytes.\n// EdgeTTS provides high-quality neural voices but requires network connection.\nfunc (e *EdgeTTS) Synthesize(ctx context.Context, text string, opts TTSSynthesisOpts) ([]byte, string, error) {\n\tvoice := opts.Voice\n\tif voice == \"\" {\n\t\tvoice = e.Voice\n\t}\n\n\t// Create secure temp file for edge-tts output\n\ttmpFile, err := os.CreateTemp(\"\", \"edge_tts_*.mp3\")\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"edge-tts: create temp file: %w\", err)\n\t}\n\ttmpPath := tmpFile.Name()\n\ttmpFile.Close()\n\tdefer os.Remove(tmpPath)\n\n\t// Use edge-tts CLI directly to avoid code injection risks\n\t// Pass text via --text argument, not via embedded code\n\targs := []string{\n\t\t\"--voice\", voice,\n\t\t\"--text\", text,\n\t\t\"--write-media\", tmpPath,\n\t}\n\n\tpath := e.Path\n\tif path == \"\" {\n\t\tpath = \"edge-tts\"\n\t}\n\tcmd := exec.CommandContext(ctx, path, args...)","sourceCodeStart":670,"sourceCodeEnd":706,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/tts.go#L670-L706","documentation":"EdgeTTS.Synthesize (core/tts.go:688) first creates a secure temp file via os.CreateTemp to hold the MP3 that the edge-tts CLI will write. This error wraps any failure of that temp-file creation with the 'edge-tts: create temp file:' prefix. It almost always reflects an OS-level problem with the temp directory, not with edge-tts itself.","triggerScenarios":"Calling EdgeTTS.Synthesize when os.CreateTemp(\"\", \"edge_tts_*.mp3\") fails — TMPDIR/TMP points to a non-existent or read-only directory, the filesystem is full (no space left on device), or the process lacks write permission on /tmp or the configured temp dir.","commonSituations":"Containerized deployments with a read-only root filesystem or a TMPDIR mounted read-only, disk-quota exhaustion on long-running daemons, sandboxed environments (e.g. systemd PrivateTmp misconfig, hardened sandboxes) that deny writes to the default temp directory.","solutions":["Check disk space on the temp filesystem (`df -h /tmp` or `$TMPDIR`) and free space if full","Verify TMPDIR/TMP/TMP_DIR env vars point to an existing, writable directory; fix or unset them","If running in a container/sandbox, make the temp directory writable or set TMPDIR to a writable volume mount","Check process permissions/SELinux policies blocking writes to the temp directory"],"exampleFix":"// before\nos.Setenv(\"TMPDIR\", \"/read-only/dir\")\naudio, format, err := edgeTTS.Synthesize(ctx, text, opts)\n// after\nos.MkdirAll(\"/var/tmp/cc-connect\", 0o755)\nos.Setenv(\"TMPDIR\", \"/var/tmp/cc-connect\")\naudio, format, err := edgeTTS.Synthesize(ctx, text, opts)","handlingStrategy":"try-catch","validationCode":"tmpDir := os.TempDir()\nif fi, err := os.Stat(tmpDir); err != nil || !fi.IsDir() {\n    return fmt.Errorf(\"temp dir %s unusable: %w\", tmpDir, err)\n}\nprobe, err := os.CreateTemp(tmpDir, \"tts_probe_*\")\nif err != nil {\n    return fmt.Errorf(\"temp dir not writable: %w\", err)\n}\nprobe.Close(); os.Remove(probe.Name())","typeGuard":null,"tryCatchPattern":"audio, format, err := edge.Synthesize(ctx, text, opts)\nif err != nil {\n    var pathErr *os.PathError\n    if errors.As(err, &pathErr) && strings.Contains(err.Error(), \"create temp file\") {\n        return fmt.Errorf(\"tts unavailable: check TMPDIR/disk space: %w\", err)\n    }\n    return err\n}","preventionTips":["Ensure TMPDIR points to an existing writable directory in containers and daemons","Monitor disk space on the temp filesystem and alert before it fills","Avoid read-only root filesystems without a writable tmp mount for processes doing TTS","Test TTS startup under systemd PrivateTmp/sandbox profiles during deployment"],"tags":["filesystem","temp-file","tts","edge-tts"],"backgroundTag":"file-open-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}