Skip to content

Conversation

@hmnd
Copy link

@hmnd hmnd commented Nov 19, 2025

potentially fixes #502

I've been running this without the crash for about half an hour, so I think it solves it. Hard to tell, because I'm still getting spammed by the Secrets mount opened by reader message, but I don't think this would introduce any further breaking behavior either.

@hmnd hmnd requested a review from a team as a code owner November 19, 2025 08:42
@hmnd
Copy link
Author

hmnd commented Nov 20, 2025

I left a dev session running on this branch for the past ~24 hrs and it's still running so I think this is indeed a viable fix!

I'm still confused what vite is doing, as it seems the endless Secrets mount opened by reader eventually stop... maybe a separate issue to file with vite.

@hmnd hmnd requested a review from Piccirello November 27, 2025 08:41
@emily-curry emily-curry requested a review from seslattery January 5, 2026 15:58
Copy link

@mikesellitto mikesellitto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I tested locally with the following test which fails on master and succeeds with the proposed changes (feel free to commit this if you care to).

@seslattery thoughts?

index bccb47c..bdd2e78 100644
--- a/pkg/controllers/secrets_test.go
+++ b/pkg/controllers/secrets_test.go
@@ -17,9 +17,13 @@ limitations under the License.
 package controllers
 
 import (
+	"os"
+	"path/filepath"
 	"strings"
 	"testing"
+	"time"
 
+	"github.com/DopplerHQ/cli/pkg/utils"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -106,3 +110,61 @@ func TestSecretsToBytes(t *testing.T) {
 		t.Errorf("Unable to convert secrets to byte array in %s format", format)
 	}
 }
+
+func TestMountSecrets(t *testing.T) {
+	if !utils.SupportsNamedPipes {
+		t.Skip("Named pipes not supported on this platform")
+	}
+
+	secrets := []byte(`{"SECRET_KEY":"secret_value"}`)
+	mountPath := filepath.Join(t.TempDir(), "secrets_mount")
+
+	path, cleanup, err := MountSecrets(secrets, mountPath, 1)
+	if !err.IsNil() {
+		t.Fatalf("MountSecrets failed: %v", err.Err)
+	}
+	defer cleanup()
+
+	time.Sleep(50 * time.Millisecond)
+
+	content, readErr := os.ReadFile(path)
+	assert.NoError(t, readErr)
+	assert.Equal(t, string(secrets), string(content))
+}
+
+func TestMountSecretsBrokenPipe(t *testing.T) {
+	if !utils.SupportsNamedPipes {
+		t.Skip("Named pipes not supported on this platform")
+	}
+
+	// large data to exceed pipe buffer and trigger EPIPE when reader closes early
+	secrets := make([]byte, 256*1024)
+	for i := range secrets {
+		secrets[i] = byte('A' + (i % 26))
+	}
+	mountPath := filepath.Join(t.TempDir(), "secrets_mount_epipe")
+
+	path, cleanup, err := MountSecrets(secrets, mountPath, 0)
+	if !err.IsNil() {
+		t.Fatalf("MountSecrets failed: %v", err.Err)
+	}
+	defer cleanup()
+
+	time.Sleep(50 * time.Millisecond)
+
+	for i := 0; i < 10; i++ {
+		f, openErr := os.OpenFile(path, os.O_RDONLY, 0)
+		if openErr != nil {
+			continue
+		}
+		f.Read(make([]byte, 1))
+		f.Close()
+		time.Sleep(5 * time.Millisecond)
+	}
+
+	time.Sleep(100 * time.Millisecond)
+
+	content, readErr := os.ReadFile(path)
+	assert.NoError(t, readErr, "mount should survive broken pipe")
+	assert.Equal(t, secrets, content)
+}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] vite dev server sometimes crashing with broken pipe error

3 participants