vxcontrol/pentagi · critical

failed to load default templates: %w

Error message

failed to load default templates: %w

What it means

newUserPrompter calls templates.LoadDefaultPromptsMap() to read the default prompt templates from the embedded filesystem (go:embed "prompts"). Failure is wrapped as "failed to load default templates: %w". Under the hood the templates are read once (sync.Once) from the embedded FS; errors come from ReadDir/ReadFile on the embedded "prompts" directory and are cached, so once it fails it keeps failing for the process lifetime.

Source

Thrown at backend/pkg/controller/prompter.go:24

	"pentagi/pkg/database"
	"pentagi/pkg/templates"
)

// newUserPrompter loads the user's custom prompts from the database and
// overlays them onto the compiled default templates. Prompt types that
// the user has not customized continue to use the defaults. A database
// error is returned to the caller so that session creation fails
// explicitly instead of silently falling back to defaults.
func newUserPrompter(ctx context.Context, db database.Querier, userID int64) (templates.Prompter, error) {
	userPrompts, err := db.GetUserPrompts(ctx, userID)
	if err != nil {
		return nil, fmt.Errorf("failed to load user prompts: %w", err)
	}

	defaults, err := templates.LoadDefaultPromptsMap()
	if err != nil {
		return nil, fmt.Errorf("failed to load default templates: %w", err)
	}

	return buildUserPrompter(defaults, userPrompts), nil
}

// buildUserPrompter is the pure merge step extracted from newUserPrompter so
// it can be unit-tested without a database fake or filesystem access. It
// mutates the supplied defaults map by overlaying each non-empty user
// override on top, then returns a Prompter backed by that map. Callers must
// pass a fresh map (e.g., from templates.LoadDefaultPromptsMap) so the
// embedded defaults are not modified.
func buildUserPrompter(defaults templates.PromptsMap, userPrompts []database.Prompt) templates.Prompter {
	for _, p := range userPrompts {
		if p.Prompt == "" {
			// The Prompts UI uses delete (or reset, which writes the
			// default body back) to remove a customization, so an empty
			// body is unexpected. Skip it instead of clobbering the
			// default with an empty string that would later surface as

View on GitHub (pinned to ea665308ba)

Solutions

  1. Rebuild the backend binary from an intact source tree so the prompts directory is embedded correctly.
  2. Verify backend/pkg/templates/prompts exists and contains *.tmpl files, and that the go:embed directive matches.
  3. Note the error is cached in sync.Once — a restart will NOT clear it; only a correct binary will.
  4. If running a custom build pipeline, ensure it does not strip or mutate embedded assets.

Example fix

// before: prompts dir missing from the embed
//go:embed prompts/*.tmpl

// after: ensure files exist and embed whole directory
//go:embed all:prompts
Defensive patterns

Strategy: validation

Validate before calling

// verify templates load before starting workers (run once at startup)
if _, err := templates.LoadDefaultPromptsMap(); err != nil {
    log.Fatalf("embedded prompt templates broken: %v", err)
}

Type guard

null

Try / catch

prompter, err := newUserPrompter(ctx, db, userID)
if err != nil {
    if strings.Contains(err.Error(), "failed to load default templates") {
        // cached in sync.Once — retrying in-process will NOT help; fail fast
        return fmt.Errorf("binary is missing embedded templates, rebuild required: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Creating or loading any flow/assistant worker when the embedded template FS read fails — realistically only a broken build/embed directive (prompts directory missing from the binary), since the templates are compiled in and not read from disk at runtime.

Common situations: Custom builds that removed or renamed the pkg/templates/prompts directory; build tooling that stripped embedded files; tampered or malformed binary after post-build processing (e.g. aggressive packing/upx or resource-stripping).

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/584312f5bf3a0a8c. Report an issue: GitHub.