shadow1ng/fscan · critical

failed to load zh.yaml: %v

Error message

failed to load zh.yaml: %v

What it means

The i18n package's init function embeds locale files (localeFS) and loads locales/zh.yaml into an go-i18n bundle at startup. If the embedded file is missing, unreadable, or not valid YAML, the package panics with this message because translations cannot work at all. It runs at program start, so it crashes the whole binary.

Source

Thrown at common/i18n/i18n.go:38

const (
	DefaultLanguage  = LangZH
	FallbackLanguage = LangEN
)

var (
	bundle    *i18n.Bundle
	localizer *i18n.Localizer
	lang      = DefaultLanguage
	mu        sync.RWMutex
)

func init() {
	bundle = i18n.NewBundle(language.Chinese)
	bundle.RegisterUnmarshalFunc("yaml", yaml.Unmarshal)

	// 从embed加载翻译文件
	if _, err := bundle.LoadMessageFileFS(localeFS, "locales/zh.yaml"); err != nil {
		panic(fmt.Sprintf("failed to load zh.yaml: %v", err))
	}
	if _, err := bundle.LoadMessageFileFS(localeFS, "locales/en.yaml"); err != nil {
		panic(fmt.Sprintf("failed to load en.yaml: %v", err))
	}

	localizer = i18n.NewLocalizer(bundle, lang, FallbackLanguage)
}

// SetLanguage 设置当前语言
func SetLanguage(l string) {
	mu.Lock()
	defer mu.Unlock()
	lang = l
	localizer = i18n.NewLocalizer(bundle, lang, FallbackLanguage)
}

// GetLanguage returns the currently configured language.
func GetLanguage() string {

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Verify common/i18n/locales/zh.yaml exists and matches the //go:embed pattern
  2. Validate zh.yaml syntax with a YAML linter/parser and fix parse errors
  3. Rebuild the binary so the embed FS picks up the current file contents
  4. Check the embed directive includes the locales directory recursively

Example fix

// before
//go:embed locales
var localeFS embed.FS // zh.yaml accidentally deleted
// after
// restore locales/zh.yaml with valid content:
// hello:
//   other: "你好"
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := localeFS.ReadFile("locales/zh.yaml"); err != nil {
    // embed pattern broken or file missing; fix before depending on i18n
}

Try / catch

// init-time panic: cannot be caught at call time; guard by adding a test
test: func TestLocalesEmbedded(t *testing.T) {
    if _, err := localeFS.ReadFile("locales/zh.yaml"); err != nil {
        t.Fatalf("zh.yaml missing from embed: %v", err)
    }
}

Prevention

When it happens

Trigger: locales/zh.yaml absent from the embedded FS (embed pattern not matching, file deleted/renamed), or zh.yaml containing YAML syntax errors that yaml.Unmarshal rejects.

Common situations: Moving/renaming the locales directory without updating the //go:embed directive, editing zh.yaml by hand and introducing bad YAML (tabs, unquoted colons), or build tags excluding the file.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/b91362aac1ebfead. Report an issue: GitHub.