gastownhall/beads · error
failed to read template %s: %w
Error message
failed to read template %s: %w
What it means
updateAgentFile builds new agent-instruction files from a template. When the target file doesn't exist and --agents-template is set, it reads that template file; a read failure (missing file, bad permissions) is wrapped here and aborts creating the agent file. Without a template flag, the embedded default (agents.EmbeddedDefault) is used instead.
Source
Thrown at cmd/bd/init_agent.go:48
}
// updateAgentFile creates or updates an agent instructions file with embedded template content.
// When a beads section already exists (legacy or current), it is updated to the latest
// versioned format so that `bd init` never silently locks in stale sections.
// If the file already has a full profile and a minimal profile is requested, the full
// profile is preserved to avoid information loss.
func updateAgentFile(filename string, verbose bool, templatePath string, profile agents.Profile, opts agents.RenderOpts) error {
// Check if file exists
//nolint:gosec // G304: filename validated by config.ValidateAgentsFile or defaulted to AGENTS.md
content, err := os.ReadFile(filename)
if os.IsNotExist(err) {
// File doesn't exist - create from template
var newContent string
if templatePath != "" {
//nolint:gosec // G304: templatePath comes from --agents-template flag
data, readErr := os.ReadFile(templatePath)
if readErr != nil {
return fmt.Errorf("failed to read template %s: %w", templatePath, readErr)
}
newContent = string(data)
} else {
newContent = agents.EmbeddedDefault()
}
// Replace the beads section with the requested profile.
// EmbeddedDefault() ships with profile:full; swap to the requested profile
// (which defaults to minimal). Also handles legacy markers without profile metadata.
if strings.Contains(newContent, "BEGIN BEADS INTEGRATION") {
if replaced, changed, err := agents.ReplaceSectionWithOpts(newContent, profile, opts); err == nil && changed {
newContent = replaced
}
}
// #nosec G306 - markdown needs to be readable
if err := os.WriteFile(filename, []byte(newContent), 0644); err != nil {
return fmt.Errorf("failed to create %s: %w", filename, err)View on GitHub (pinned to 71377f2769)
Solutions
- Verify the --agents-template path exists and is readable (ls -l / cat the file)
- Use an absolute path for --agents-template
- Omit --agents-template to use the built-in embedded default template
- Check file permissions on the template and working directory
Example fix
// before bd init --agents-template ./templates/agents.tmpl # file missing // after bd init --agents-template /abs/path/templates/agents.tmpl # or drop the flag entirely: bd init
Defensive patterns
Strategy: validation
Validate before calling
if [ -n "$TEMPLATE" ] && [ ! -r "$TEMPLATE" ]; then echo "template unreadable: $TEMPLATE" >&2; exit 1; fi
Try / catch
if err := addAgentsInstructions(...); err != nil && strings.Contains(err.Error(), "failed to read template") { /* fix path or drop --agents-template */ } Prevention
- Verify template paths with an absolute path
- Test `cat <template>` before passing it to --agents-template
- Use the embedded default when a custom template isn't required
- Mount templates read-accessibly in containers
When it happens
Trigger: bd init (or addAgentsInstructions) run with --agents-template pointing to a nonexistent or unreadable path, in a repo where the target agent markdown (e.g. AGENTS.md) does not yet exist.
Common situations: Typo in --agents-template path; template lives outside the sandbox's allowed mounts; relative path resolved from an unexpected working directory; unreadable permissions on the template.
Related errors
- failed to create %s: %w
- failed to read %s: %w
- failed to update %s: %w
- failed to create .beads directory: %v Permission denied. Ch
- failed to create .beads directory: %v
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/c621e2177dbea300.
Report an issue: GitHub.