Skip to content

fix: handle broken pipe error while rapidly reading from secrets mount - #503

Merged
emily-curry merged 4 commits into
DopplerHQ:masterfrom
hmnd:push-tllrtpwqlspw
Jan 27, 2026
Merged

emily-curry merged 4 commits into
DopplerHQ:masterfrom
hmnd:push-tllrtpwqlspw

Conversation

@hmnd

@hmnd hmnd commented Nov 19, 2025

Copy link
Copy Markdown
Contributor

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
Comment thread pkg/controllers/secrets.go Outdated
@hmnd

hmnd commented Nov 20, 2025

Copy link
Copy Markdown
Contributor Author

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
Comment thread pkg/controllers/secrets.go Outdated
@emily-curry
emily-curry requested a review from seslattery January 5, 2026 15:58
mikesellitto
mikesellitto previously approved these changes Jan 9, 2026

@mikesellitto mikesellitto left a comment

Copy link
Copy Markdown
Contributor

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)
+}

@hmnd

hmnd commented Jan 11, 2026

Copy link
Copy Markdown
Contributor Author

@mikesellitto Thanks! I removed the time.Sleep(100 * time.Millescond) before the last read, as ReadFile block until MountSecrets calls OpenFile anyway. I also set maxReads=11 since we're reading it a deterministic number of times.

@seslattery seslattery left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me!

@emily-curry emily-curry left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the contribution! This looks good to me as well.

@emily-curry
emily-curry merged commit 772859f into DopplerHQ:master Jan 27, 2026
5 of 6 checks passed
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

5 participants