# TASK.md — Debug: App Info Page — YAML Parsing Failure > Read CLAUDE.md first for project context, workspace layout, and build instructions. ## Problem The `/apps/romm` info page shows NO app info content (no tagline, no use cases, no optional config form). More importantly, even basic metadata is missing: - `~ RAM` badge shows no value (should be "300M") - Category badge is empty (should be "media") - Tagline `

` is empty These fields have been in `.felhom.yml` since BEFORE the `app_info` section was added. If they're empty, it means `LoadMetadata()` is silently failing and returning defaults. ## Root cause analysis `LoadMetadata()` in `internal/stacks/metadata.go` swallows YAML parse errors: ```go if err := yaml.Unmarshal(data, &meta); err != nil { // Parse error — still return defaults <-- NO LOG OUTPUT! dirName := filepath.Base(stackDir) meta.DisplayName = toTitleCase(strings.ReplaceAll(dirName, "-", " ")) meta.Slug = dirName return meta } ``` The YAML parse is failing for some reason, and the error is silently ignored. ## Step 1: Diagnose — check what the controller has in memory Run this from your workstation to see the raw API data for romm: ```bash # Get a session first, then check the stack data ssh kisfenyo@192.168.0.162 "curl -s http://localhost:8080/api/stacks" 2>/dev/null | head -200 ``` Wait — API needs auth. Easier approach: add a temporary debug log. ## Step 2: Add error logging to LoadMetadata In `controller/internal/stacks/metadata.go`, the `LoadMetadata` function currently swallows parse errors silently. **Add logging** so we can see what's failing: ```go func LoadMetadata(stackDir string) Metadata { meta := Metadata{} path := filepath.Join(stackDir, ".felhom.yml") data, err := os.ReadFile(path) if err != nil { dirName := filepath.Base(stackDir) meta.DisplayName = toTitleCase(strings.ReplaceAll(dirName, "-", " ")) meta.Slug = dirName meta.Category = "tools" return meta } if err := yaml.Unmarshal(data, &meta); err != nil { // ADD THIS LOG LINE — this is critical for debugging fmt.Fprintf(os.Stderr, "[ERROR] Failed to parse .felhom.yml in %s: %v\n", stackDir, err) dirName := filepath.Base(stackDir) meta.DisplayName = toTitleCase(strings.ReplaceAll(dirName, "-", " ")) meta.Slug = dirName return meta } // ADD THIS DEBUG LINE — confirms successful parse fmt.Fprintf(os.Stderr, "[DEBUG] Loaded metadata for %s: tagline=%q, useCases=%d, optConfig=%d\n", filepath.Base(stackDir), meta.AppInfo.Tagline, len(meta.AppInfo.UseCases), len(meta.OptionalConfig)) // ... rest of function unchanged ... ``` You'll need to add `"fmt"` to the imports if not already there. ## Step 3: Build, deploy, check logs Follow the CLAUDE.md build workflow. After deploying, immediately check logs: ```bash ssh kisfenyo@192.168.0.162 "docker logs felhom-controller 2>&1 | grep -E 'ERROR.*felhom.yml|DEBUG.*Loaded metadata'" ``` This will show either: - `[ERROR] Failed to parse .felhom.yml in /opt/docker/stacks/romm: ` — tells us exactly what's wrong - `[DEBUG] Loaded metadata for romm: tagline="Retró...", useCases=5, optConfig=1` — parsing works, problem is elsewhere ## Step 4: Fix based on diagnosis ### If YAML parse error: The error message will tell us exactly what's wrong. Common causes: - **Special Unicode characters** in quoted strings (Hungarian quotes `„"`, em-dash `—`) - **Encoding issue** (BOM character at start of file) - **Indentation** mismatch Fix the `.felhom.yml` content accordingly in the app-catalog repo, commit + push, trigger sync. ### If parsing succeeds but data still missing: The problem is in how `ScanStacks()` stores/retrieves metadata. Check: - Does `GetStacks()` return the full `Meta` field? - Is there any code that creates a new `Metadata{}` after `LoadMetadata()`? ## Step 5: After fixing, clean up debug logging Once the issue is resolved: 1. Keep the `[ERROR]` log line (it should have been there from the start — silent failures are bad) 2. Remove or gate the `[DEBUG]` line behind `isDebug()` check (or just remove it) 3. Build + deploy the final version ## Build workflow fix for CLAUDE.md Also update the deploy command in CLAUDE.md. The `sed` approach for updating the image tag is fragile — it matched the service name line too and broke the YAML last time. Replace Step 3 in CLAUDE.md with this safer approach: ```bash # Deploy on demo node — use targeted sed that only matches the 'image:' line ssh kisfenyo@192.168.0.162 "cd /opt/docker/felhom-controller && sudo docker pull gitea.dooplex.hu/admin/felhom-controller: && sudo sed -i 's|image: gitea.dooplex.hu/admin/felhom-controller:.*|image: gitea.dooplex.hu/admin/felhom-controller:|' docker-compose.yml && sudo docker compose up -d" ``` Key differences from previous command: - `sudo` for both sed and docker compose (the directory is root-owned) - sed pattern matches `image: gitea.dooplex.hu/admin/felhom-controller:.*` — only the image line, not the service name - Single SSH command to avoid partial failures Update the CLAUDE.md file with this corrected deploy command. ## Summary The core issue is that `LoadMetadata()` silently swallows YAML parse errors. Even if the fix turns out to be a simple YAML syntax issue, the error logging should be added permanently — silent failures make debugging impossible.