Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions pkg/bundle/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func Operation(arguments map[string]string, operation *base.Operation) (tb datab
// Iterate over each write operation.
for _, w := range rWrites {
// Parse the write operation string into a template.
tmpl, err := template.New("template").Parse(w)
tmpl, err := template.New("template").Option("missingkey=zero").Parse(w)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

missingkey=zero silently produces malformed tuples/attributes — prefer missingkey=error

missingkey=zero returns the zero value (empty string for map[string]string) for missing keys, while missingkey=error stops execution immediately with an error. With missingkey=zero, a template like user:{{.user_id}}#member@group:{{.group_id}} with a missing group_id silently renders as user:alice#member@group:, which gets passed to tuple.Tuple() / attribute.Attribute(). The downstream parser may return an error, but it will describe a malformed string rather than the actual root cause (missing argument key), making debugging harder. If the downstream parser happens to accept a truncated string, data corruption occurs silently.

missingkey=error surfaces the missing key immediately with a clear error, which is the correct behaviour for a required-argument template substitution.

🐛 Proposed fix — use `missingkey=error` in all four loops
-		tmpl, err := template.New("template").Option("missingkey=zero").Parse(w)
+		tmpl, err := template.New("template").Option("missingkey=error").Parse(w)

Apply the same change to lines 58, 94, and 130.

Also applies to: 58-58, 94-94, 130-130

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/bundle/bundle.go` at line 22, The template parsing currently uses
template.New("template").Option("missingkey=zero").Parse(w) which silently
substitutes missing keys; change the Option to "missingkey=error" so
template.New("template").Option("missingkey=error").Parse(w) to surface
missing-key errors; update this replacement in all four occurrences (the
template.New(...).Option(...).Parse(w) calls found in the four loops in
pkg/bundle/bundle.go).

if err != nil {
return tb, ab, err
}
Expand Down Expand Up @@ -55,7 +55,7 @@ func Operation(arguments map[string]string, operation *base.Operation) (tb datab
// Iterate over each delete operation.
for _, w := range rDeletes {
// Parse the write operation string into a template.
tmpl, err := template.New("template").Parse(w)
tmpl, err := template.New("template").Option("missingkey=zero").Parse(w)
if err != nil {
return tb, ab, err
}
Expand Down Expand Up @@ -91,7 +91,7 @@ func Operation(arguments map[string]string, operation *base.Operation) (tb datab
// Iterate over each write operation.
for _, w := range aWrites {
// Parse the write operation string into a template.
tmpl, err := template.New("template").Parse(w)
tmpl, err := template.New("template").Option("missingkey=zero").Parse(w)
if err != nil {
return tb, ab, err
}
Expand Down Expand Up @@ -127,7 +127,7 @@ func Operation(arguments map[string]string, operation *base.Operation) (tb datab
// Iterate over each delete operation.
for _, w := range aDeletes {
// Parse the write operation string into a template.
tmpl, err := template.New("template").Parse(w)
tmpl, err := template.New("template").Option("missingkey=zero").Parse(w)
if err != nil {
return tb, ab, err
}
Expand Down
Loading