siyuan-note/siyuan · error
built-in marketplace package cannot be overwritten
Error message
built-in marketplace package cannot be overwritten
What it means
Thrown by InstallLocalBazaarPackage when installing an uploaded local archive whose package name collides with a built-in theme (daylight or midnight) or built-in icon (litheness). Built-in appearance assets are protected from overwrite because replacing them can break the default UI.
Source
Thrown at kernel/model/bazaar.go:628
// InstallLocalBazaarPackage 安装上传的本地集市包。
func InstallLocalBazaarPackage(archivePath, frontend string, overwrite bool) (result *LocalBazaarPackageInstallResult, err error) {
pkgType, pkg, sourcePath, cleanup, err := bazaar.ExtractLocalPackage(archivePath)
if err != nil {
return nil, err
}
defer cleanup()
result = &LocalBazaarPackageInstallResult{
PackageType: pkgType,
PackageName: pkg.Name,
MinAppVersion: pkg.MinAppVersion,
}
installPath, _, err := getPackageInstallPath(pkgType, pkg.Name)
if err != nil {
return result, err
}
if (pkgType == "themes" && isBuiltInTheme(pkg.Name)) || (pkgType == "icons" && isBuiltInIcon(pkg.Name)) {
return result, errors.New("built-in marketplace package cannot be overwritten")
}
if bazaar.IsBelowRequiredAppVersion(pkg) {
return result, fmt.Errorf("%w: SiYuan %s or later is required", ErrLocalBazaarPackageIncompatible, pkg.MinAppVersion)
}
if (pkgType == "plugins" && bazaar.IsIncompatiblePlugin(pkg, frontend)) ||
(pkgType == "themes" && bazaar.IsIncompatibleTheme(pkg, frontend)) {
return result, ErrLocalBazaarPackageIncompatible
}
localBazaarInstallLock.Lock()
defer localBazaarInstallLock.Unlock()
_, statErr := os.Lstat(installPath)
if statErr != nil && !os.IsNotExist(statErr) {
return result, statErr
}
result.Updated = statErr == nil
if result.Updated && !overwrite {
return result, ErrLocalBazaarPackageExistsView on GitHub (pinned to 251596fc0d)
Solutions
- Rename the package in its manifest (theme.json/icon.json) and archive to a non-built-in name before installing.
- If you genuinely need a custom default, distribute it as a separate package rather than overwriting the built-in.
Example fix
// theme.json
// before
{ "name": "daylight", ... }
// after
{ "name": "my-daylight", ... } Defensive patterns
Strategy: validation
Validate before calling
// Block built-in names before attempting local install.
if (pkgType == "themes" && (strings.EqualFold(pkg.Name, "daylight") || strings.EqualFold(pkg.Name, "midnight"))) ||
(pkgType == "icons" && strings.EqualFold(pkg.Name, "litheness")) {
return fmt.Errorf("cannot overwrite built-in package %q", pkg.Name)
} Type guard
func isBuiltInPkgName(pkgType, name string) bool {
switch pkgType {
case "themes":
return strings.EqualFold(name, "daylight") || strings.EqualFold(name, "midnight")
case "icons":
return strings.EqualFold(name, "litheness")
}
return false
} Prevention
- Give custom themes/icons unique manifest names; never reuse built-in names.
- Validate against the built-in name set before uploading a local archive.
- Remember the comparison is case-insensitive (EqualFold).
When it happens
Trigger: Uploading and installing a local theme archive whose manifest name is 'daylight' or 'midnight', or a local icon archive whose name is 'litheness'. The check uses case-insensitive comparison (strings.EqualFold), so casing variants are also blocked.
Common situations: A user or packaging tool reused a built-in package name for a custom theme/icon, or tried to 'replace' the default appearance. The guard prevents corrupting the fallback theme/icon.
Related errors
- invalid package name
- invalid package type
- ErrLocalBazaarPackageExists
- ErrLocalBazaarPackageIncompatible
- installed package not found
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/6441cad48faf7a4e.
Report an issue: GitHub.