chatboxai/chatbox · error · Error

Failed to create temporary export file

Error message

Failed to create temporary export file

What it means

Thrown by exportStreamingFileWithSystemPicker after all streamed chunks have been flushed and the final guard still cannot find a temp file URI. The method relies on Capacitor's Filesystem.writeFile (Directory.Cache) to allocate tempUri on the first flush; if that call never produced a usable uri the export cannot be handed to AndroidDocumentSaver. This is the Android document-export fast path, so it only fires on Capacitor-backed Android builds.

Source

Thrown at src/renderer/platform/filter_writer.ts:552

        directory: Directory.Cache,
        encoding: Encoding.UTF8,
      })
    }

    try {
      for await (const chunk of dataCallback()) {
        bufferedContent += chunk
        if (bufferedContent.length >= chunkSize) {
          await flush()
        }
      }

      if (bufferedContent || !tempUri) {
        await flush()
      }

      if (!tempUri) {
        throw new Error('Failed to create temporary export file')
      }

      log.warn('exportStreamingFileWithSystemPicker:tempWritten', {
        filename,
        path: tempPath,
        uri: tempUri,
        chunkCount,
        totalLength,
      })

      const saveResult = await AndroidDocumentSaver.saveFile({
        sourceUri: tempUri,
        suggestedName: filename,
        mimeType,
      })
      log.warn('exportStreamingFileWithSystemPicker:pickerSaved', saveResult)
      await this.handlePostWrite({ uri: saveResult.uri })
    } finally {

View on GitHub (pinned to 81571269ad)

Solutions

  1. Check the return of Filesystem.writeFile in flush() and throw/log when result.uri is missing instead of letting tempUri stay undefined.
  2. Verify the Capacitor Filesystem plugin is installed and registered in capacitor.config and the Android MainActivity.
  3. Ensure the app has cache write access and free space; surface a readable quota/permission error from Filesystem rather than the generic message.
  4. Guard the empty-stream case explicitly: when dataCallback yields nothing, write a minimal placeholder before asserting tempUri.

Example fix

// before
const result = await Filesystem.writeFile({ path: tempPath, data: content, directory: Directory.Cache, encoding: Encoding.UTF8, recursive: true })
tempUri = result.uri
// after
const result = await Filesystem.writeFile({ path: tempPath, data: content, directory: Directory.Cache, encoding: Encoding.UTF8, recursive: true })
if (!result?.uri) throw new Error('Filesystem.writeFile returned no uri (cache unwritable or plugin missing)')
tempUri = result.uri
Defensive patterns

Strategy: validation

Validate before calling

// Before exporting, probe the Cache directory is writable
import { Filesystem, Directory } from '@capacitor/filesystem'
async function canWriteCache(): Promise<boolean> {
  try {
    const probe = await Filesystem.writeFile({ path: '__probe__', data: 'x', directory: Directory.Cache, recursive: true })
    await Filesystem.deleteFile({ path: '__probe__', directory: Directory.Cache })
    return Boolean(probe?.uri)
  } catch {
    return false
  }
}

Type guard

function hasUri(r: unknown): r is { uri: string } {
  return typeof r === 'object' && r !== null && typeof (r as { uri?: unknown }).uri === 'string' && !!(r as { uri?: unknown }).uri
}

Try / catch

try {
  await exportStreamingFileWithSystemPicker(name, cb)
} catch (err) {
  if (err instanceof Error && err.message === 'Failed to create temporary export file') {
    notifyUser('Export failed: cache directory is not writable. Free space or restart the app.')
  } else throw err
}

Prevention

When it happens

Trigger: The async dataCallback yields content, flush() runs Filesystem.writeFile/appendFile into the Cache directory, but tempUri remains undefined after the terminal flush at line 547-549. Concretely: Filesystem.writeFile resolves without a .uri field, the Cache directory is unwritable (permissions, disk full / ENOSPC), or the Capacitor Filesystem plugin is not registered on the web layer so the call silently no-ops.

Common situations: Android device with restricted scoped-storage cache permissions, low-storage device where Cache writes fail, a misconfigured Capacitor build missing the Filesystem plugin, or an OS cleanup that invalidated the cache path mid-stream. Also seen when dataCallback() yields zero chunks and the empty-content writeFile returns no uri.

Related errors


AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12). Data as JSON: /api/errors/db3d1e2abede98cc. Report an issue: GitHub.