anomalyco/sst · error

failed to read file %s: %w

Error message

failed to read file %s: %w

What it means

handleUpdate builds a multipart request to upload the worker script to Cloudflare and first reads the local script file (input.Content.Filename). This error wraps os.ReadFile failure: the file does not exist, the path is wrong, or the process lacks read permission. The wrapped os error names the exact reason.

Source

Thrown at pkg/server/resource/cloudflare-worker-script.go:157

}

func (r *WorkerScript) Delete(input *DeleteInput[WorkerScriptOutputs], output *int) error {
	err := r.handleDelete(&input.Outs)
	if err != nil {
		return err
	}

	return nil
}

func (r *WorkerScript) handleUpdate(input *WorkerScriptInputs) error {
	var body bytes.Buffer
	writer := multipart.NewWriter(&body)

	// Add file content to form data
	fileContent, err := os.ReadFile(input.Content.Filename)
	if err != nil {
		return fmt.Errorf("failed to read file %s: %w", input.Content.Filename, err)
	}

	contentType := "application/javascript"
	if input.MainModule != "" {
		input.MainModule = input.Content.Hash
		contentType = "application/javascript+module"
	}

	contentPart, err := writer.CreatePart(map[string][]string{
		"Content-Disposition": []string{fmt.Sprintf(`form-data; name="%s"; filename="%s"`, input.Content.Hash, input.Content.Hash)},
		"Content-Type":        []string{contentType},
	})
	if err != nil {
		return fmt.Errorf("failed to create form part %s: %w", input.Content.Hash, err)
	}

	_, err = contentPart.Write([]byte(fileContent))
	if err != nil {

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Check the path in the error exists: ls the reported filename
  2. Rebuild (sst build / redeploy) so the output artifact is regenerated at the expected path
  3. Run the CLI from the project root so relative paths resolve correctly
  4. Fix file permissions (chmod) or run under an account that can read the file
  5. Expand ~ or absolute-ize the path before storing it in state

Example fix

// before
fileContent, err := os.ReadFile(input.Content.Filename)
if err != nil {
	return fmt.Errorf("failed to read file %s: %w", input.Content.Filename, err)
}
// after
path := input.Content.Filename
if strings.HasPrefix(path, "~") {
	home, _ := os.UserHomeDir()
	path = filepath.Join(home, strings.TrimPrefix(path, "~"))
}
if _, err := os.Stat(path); os.IsNotExist(err) {
	return fmt.Errorf("worker script %q does not exist; run a build before deploy", path)
}
fileContent, err := os.ReadFile(path)
if err != nil {
	return fmt.Errorf("failed to read file %s: %w", path, err)
}
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(input.Content.Filename); err != nil {
	return fmt.Errorf("worker script %s unavailable before upload: %w", input.Content.Filename, err)
}

Type guard

func fileReadable(path string) bool {
	f, err := os.Open(path)
	if err != nil {
		return false
	}
	f.Close()
	return true
}

Try / catch

fileContent, err := os.ReadFile(input.Content.Filename)
if err != nil {
	if os.IsNotExist(err) {
		return fmt.Errorf("worker script %s not found; run build first", input.Content.Filename)
	}
	return fmt.Errorf("failed to read file %s: %w", input.Content.Filename, err)
}

Prevention

When it happens

Trigger: os.ReadFile(input.Content.Filename) fails in handleUpdate (pkg/server/resource/cloudflare-worker-script.go:157), invoked from Create/Update when the bundled worker script cannot be found at the recorded path on disk.

Common situations: Deploying from a different working directory or machine than where the build emitted the script; stale .sst state referencing a file cleaned by a rebuild; file deleted between build and deploy; read permissions on CI; path containing ~ that was never expanded.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30). Data as JSON: /api/errors/755f8d7b5fe4560e. Report an issue: GitHub.