Skip to content

Commit 5a87c83

Browse files
dgellowclaude
andcommitted
fix: strip surrounding quotes from environment variable values
Fixes issue where systemd/Docker env files with quoted values like ENCRYPTION_KEY="32-char-key" were parsed with quotes included, causing "34 bytes" errors in production. Changes: - Strip matching surrounding quotes (single or double) from env values - Only strip if quotes match at both ends (e.g., "value" or 'value') - Preserve internal quotes and mismatched quotes - Add comprehensive test coverage for quote handling This resolves the production issue where JWT secrets and encryption keys were failing validation due to included quotes from .env files. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 17665b0 commit 5a87c83

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

internal/config/types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ func parseConfigValue(raw json.RawMessage) (*RawConfigValue, error) {
167167
if value == "" {
168168
return nil, fmt.Errorf("environment variable %s not set", envVar)
169169
}
170+
// Strip surrounding quotes if present (only matching pairs)
171+
if len(value) >= 2 {
172+
if (value[0] == '"' && value[len(value)-1] == '"') ||
173+
(value[0] == '\'' && value[len(value)-1] == '\'') {
174+
value = value[1 : len(value)-1]
175+
}
176+
}
170177
return &RawConfigValue{value: value, needsUserToken: false}, nil
171178
}
172179

internal/config/unmarshal_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,41 @@ func TestParseConfigValue(t *testing.T) {
3131
expectedValue: "test value",
3232
expectedToken: false,
3333
},
34+
{
35+
name: "env reference with double quotes",
36+
input: `{"$env": "QUOTED_VAR"}`,
37+
envVars: map[string]string{"QUOTED_VAR": `"quoted value"`},
38+
expectedValue: "quoted value",
39+
expectedToken: false,
40+
},
41+
{
42+
name: "env reference with single quotes",
43+
input: `{"$env": "SINGLE_QUOTED"}`,
44+
envVars: map[string]string{"SINGLE_QUOTED": `'single quoted'`},
45+
expectedValue: "single quoted",
46+
expectedToken: false,
47+
},
48+
{
49+
name: "env reference with mixed quotes not stripped",
50+
input: `{"$env": "MIXED_QUOTES"}`,
51+
envVars: map[string]string{"MIXED_QUOTES": `"mixed quotes'`},
52+
expectedValue: `"mixed quotes'`,
53+
expectedToken: false,
54+
},
55+
{
56+
name: "env reference with no surrounding quotes",
57+
input: `{"$env": "NO_QUOTES"}`,
58+
envVars: map[string]string{"NO_QUOTES": `no quotes`},
59+
expectedValue: "no quotes",
60+
expectedToken: false,
61+
},
62+
{
63+
name: "env reference with internal quotes preserved",
64+
input: `{"$env": "INTERNAL_QUOTES"}`,
65+
envVars: map[string]string{"INTERNAL_QUOTES": `"value with "internal" quotes"`},
66+
expectedValue: `value with "internal" quotes`,
67+
expectedToken: false,
68+
},
3469
{
3570
name: "missing env var",
3671
input: `{"$env": "MISSING_VAR"}`,

0 commit comments

Comments
 (0)