on main help sign in
docs: update resolver godoc to match lenient default

The godoc on the shell variable resolver still said unset variables were a hard error. Updated to match the new lenient default and to point at ${VAR:?message} as the way to require a value. Co-Authored-By: Charm Crush <crush@charm.land>

commit45f7484b495a6ec4e155d38a82a9935bdb11d8a5 authorChristian Rocha <christian@rocha.is> dateSun 3 May 2026, 17:02 (6 months ago) parenta28aded
1 file changed+11−5
internal/config/resolve.go+11−5
internal/config/resolve.go+11−5
@@ -58,8 +58,11 @@ type shellVariableResolver struct {
5858// NewShellVariableResolver returns a VariableResolver that delegates to
5959// the embedded shell (the same interpreter used by the bash tool and
6060// hooks). Supported constructs match shell.ExpandValue: $VAR, ${VAR},
61−// ${VAR:-default}, $(command), quoting, and escapes. Unset variables are
62−// an error; use ${VAR:-} to opt in to an empty fallback.
61+// ${VAR:-default}, $(command), quoting, and escapes. Unset variables
62+// expand to the empty string by default, matching bash; use
63+// ${VAR:?message} to require a value and fail loudly when it is missing.
64+// The stricter "unset is always an error" mode is gated globally by
65+// shell.NoUnset.
6366func NewShellVariableResolver(e env.Env, opts ...ShellResolverOption) VariableResolver {
6467 r := &shellVariableResolver{
6568 env: e,
@@ -77,9 +80,12 @@ func NewShellVariableResolver(e env.Env, opts ...ShellResolverOption) VariableRe
7780// - $VAR and ${VAR} for environment variables.
7881// - ${VAR:-default} / ${VAR:+alt} / ${VAR:?msg} for defaulting.
7982//
80−// Unset variables are a hard error (nounset), mirroring the historical
81−// behaviour of this resolver: silently expanding an unset variable to the
82−// empty string is exactly how broken credentials reach MCP servers.
83+// Unset variables expand to the empty string by default, matching bash.
84+// Command-substitution failures are always a hard error. Required
85+// credentials should use ${VAR:?message} so a missing variable fails
86+// loudly at load time instead of quietly resolving to empty. Global
87+// strict mode is available via shell.NoUnset for callers that want the
88+// old nounset-on behaviour back.
8389func (r *shellVariableResolver) ResolveValue(value string) (string, error) {
8490 // Preserve the historical backward-compat contract: a lone "$" is a
8591 // malformed config value, not a legal literal. The underlying shell