{"record":{"id":"0216d4289c0c5110","repo":"glanceapp/glance","slug":"no-pages-configured","errorCode":null,"errorMessage":"no pages configured","messagePattern":"no pages configured","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/glance/config.go","lineNumber":453,"sourceCode":"\n\tonChange(lastContents)\n\n\treturn func() error {\n\t\tif debounceTimer != nil {\n\t\t\tdebounceTimer.Stop()\n\t\t}\n\n\t\treturn watcher.Close()\n\t}, nil\n}\n\n// TODO: Refactor, we currently validate in two different places, this being\n// one of them, which doesn't modify the data and only checks for logical errors\n// and then again when creating the application which does modify the data and do\n// further validation. Would be better if validation was done in a single place.\nfunc isConfigStateValid(config *config) error {\n\tif len(config.Pages) == 0 {\n\t\treturn fmt.Errorf(\"no pages configured\")\n\t}\n\n\tif len(config.Auth.Users) > 0 && config.Auth.SecretKey == \"\" {\n\t\treturn fmt.Errorf(\"secret-key must be set when users are configured\")\n\t}\n\n\tfor username := range config.Auth.Users {\n\t\tif username == \"\" {\n\t\t\treturn fmt.Errorf(\"user has no name\")\n\t\t}\n\n\t\tif len(username) < 3 {\n\t\t\treturn errors.New(\"usernames must be at least 3 characters\")\n\t\t}\n\n\t\tuser := config.Auth.Users[username]\n\n\t\tif user.Password == \"\" {","sourceCodeStart":435,"sourceCodeEnd":471,"githubUrl":"https://github.com/glanceapp/glance/blob/91324e8de762702e97b0ac5c8e36271d644d8642/internal/glance/config.go#L435-L471","documentation":"Config validation (isConfigStateValid) rejects a configuration whose pages list is empty. Glance renders pages; with zero pages there is nothing to serve, so the config is considered logically invalid even though it parses.","triggerScenarios":"A glance.yml that defines server/auth settings but contains no pages: block, or whose only page is commented out; also a config assembled entirely from !include files where the page include failed silently at the YAML level (e.g. included content merged under the wrong key).","commonSituations":"Starting from a template and deleting the example pages; includes that inject widgets but no top-level pages key; YAML indentation putting pages under another section.","solutions":["Add at least one page with a title and columns to glance.yml","If using includes, verify the merged result still has a top-level pages: list (check indentation of the included content)","Uncomment or restore a previously removed page block"],"exampleFix":"# before\nserver:\n  port: 8080\n# after\nserver:\n  port: 8080\npages:\n  - name: Home\n    columns:\n      - size: full\n        widgets: []","handlingStrategy":"validation","validationCode":"// After unmarshal, before starting the app:\nif len(cfg.Pages) == 0 {\n    return errors.New(\"refusing to start: no pages configured\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always base new configs on the documented minimal example with one page","After include refactors, render the merged config and check the pages key exists"],"tags":["glance","configuration","validation","yaml"],"backgroundTag":null,"analyzedSha":"91324e8de762702e97b0ac5c8e36271d644d8642","analyzedAt":"2026-08-15T14:12:54.279Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}