{"record":{"id":"30e5fedd93f22023","repo":"siyuan-note/siyuan","slug":"invalid-layer-position-s","errorCode":null,"errorMessage":"invalid layer position [%s]","messagePattern":"invalid layer position \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/boot_appearance.go","lineNumber":492,"sourceCode":"\t\t\t}\n\t\t} else if layer.Poster != \"\" {\n\t\t\terr = errors.New(\"image layer cannot declare a poster\")\n\t\t\treturn nil, err\n\t\t}\n\t\tfit := layer.Fit\n\t\tif fit == \"\" {\n\t\t\tfit = \"cover\"\n\t\t}\n\t\tif !isValidBootAppearanceFit(fit) {\n\t\t\terr = fmt.Errorf(\"invalid layer fit [%s]\", fit)\n\t\t\treturn nil, err\n\t\t}\n\t\tposition := layer.Position\n\t\tif position == \"\" {\n\t\t\tposition = \"center\"\n\t\t}\n\t\tif !isValidBootAppearancePosition(position) {\n\t\t\terr = fmt.Errorf(\"invalid layer position [%s]\", position)\n\t\t\treturn nil, err\n\t\t}\n\t\titem := &BootAppearanceLayer{\n\t\t\tID:       layer.ID,\n\t\t\tType:     layer.Type,\n\t\t\tSrc:      bootAppearanceAssetURL(pkg.Name, appearanceID, layer.Src),\n\t\t\tFit:      fit,\n\t\t\tPosition: position,\n\t\t}\n\t\tif layer.Poster != \"\" {\n\t\t\titem.Poster = bootAppearanceAssetURL(pkg.Name, appearanceID, layer.Poster)\n\t\t}\n\t\tret.Layers = append(ret.Layers, item)\n\t}\n\treturn\n}\n\nfunc validateBootAppearancePackage(pluginDir, appearanceDir string) error {","sourceCodeStart":474,"sourceCodeEnd":510,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/boot_appearance.go#L474-L510","documentation":"Thrown by loadBootAppearance when a layer's \"position\" value is not one of the nine accepted keywords. Empty positions default to \"center\", so the error indicates an explicitly invalid string. Loading the boot appearance package fails entirely.","triggerScenarios":"GetBootAppearances or getBootAppearanceByID reading a manifest whose layer position is e.g. \"middle\", \"top left\" (space instead of hyphen), or \"Center\" (wrong case).","commonSituations":"Authors writing CSS-style values (\"center center\", \"50% 50%\"), using spaces instead of hyphens, or wrong casing in hand-edited manifests.","solutions":["Change the layer's position in the manifest to one of: center, top, right, bottom, left, top-left, top-right, bottom-right, bottom-left (lowercase, hyphenated).","Remove the position field to get the default \"center\".","Spell composite positions with a hyphen (top-left), not a space."],"exampleFix":"// before\n\"position\": \"top left\"\n// after\n\"position\": \"top-left\"","handlingStrategy":"validation","validationCode":"function validLayerPosition(p) { return !p || [\"center\",\"top\",\"right\",\"bottom\",\"left\",\"top-left\",\"top-right\",\"bottom-right\",\"bottom-left\"].includes(p); }","typeGuard":"const isLayerPosition = (v) => typeof v === \"string\" && [\"center\",\"top\",\"right\",\"bottom\",\"left\",\"top-left\",\"top-right\",\"bottom-right\",\"bottom-left\"].includes(v);","tryCatchPattern":"try { app = await getBootAppearanceByID(id); } catch (e) { if (String(e).includes(\"invalid layer position\")) { /* correct manifest position field */ } else throw e; }","preventionTips":["Use hyphenated lowercase keywords, never spaces or percentages","Lint manifests against the nine allowed positions","Omit position to get center by default"],"tags":["validation","boot-appearance","manifest"],"backgroundTag":"invalid-enum-value","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}