Bug: read files fails silently #77

Closed
opened 2026-04-20 08:52:09 +00:00 by fatmaebrahim · 3 comments
Member

Summary

Broken TTS (Read Aloud) API endpoint when embedded behind a proxy.
The voice TTS fetch URL is constructed as BASE_PATH '/../hero_agent/api/voice/tts', which produces incorrect paths when the app is embedded inside hero_os at /hero_books/ui/.
The relative /../ navigation doesn't resolve correctly in all proxy configurations, causing the Read Aloud feature to fail.

Steps to Reproduce

  1. Open hero_books embedded inside hero_os (e.g. at /hero_books/ui/)
  2. Navigate to any book page
  3. Click the Read button
  4. The TTS request fails — no audio is played
### Summary Broken TTS (Read Aloud) API endpoint when embedded behind a proxy. The voice TTS fetch URL is constructed as BASE_PATH _'/../hero_agent/api/voice/tts'_, which produces incorrect paths when the app is embedded inside hero_os at /hero_books/ui/. The relative /../ navigation doesn't resolve correctly in all proxy configurations, causing the Read Aloud feature to fail. ### Steps to Reproduce 1. Open hero_books embedded inside hero_os (e.g. at /hero_books/ui/) 2. Navigate to any book page 3. Click the Read button 4. The TTS request fails — no audio is played
Author
Member

Implementation Spec for Issue #77

Objective

Fix the Read Aloud (TTS) feature in the hero_books page viewer so it works correctly when the application is embedded inside hero_os at /hero_books/ui/. The bug has two parts: (1) the TTS fetch URL uses a broken relative path via BASE_PATH + '/../hero_agent/api/voice/tts', and (2) a misplaced closing </div> tag causes the {% endblock %} directives to sit inside the wrong element.

Requirements

  • Replace the TTS fetch URL BASE_PATH + '/../hero_agent/api/voice/tts' with the absolute path /hero_agent/ui/api/voice/tts so the request resolves correctly regardless of proxy configuration or embedded path prefix.
  • Move the closing </div> for <div class="row"> so it appears after closing col-lg-9 and before {% endblock %}, rather than after {% endblock %} at the very end of the file.
  • Ensure the file ends with a trailing newline (POSIX convention).
  • Remove the spurious blank line inside the if (!data.audio) block.

Files to Modify

File Description
crates/hero_books_ui/templates/page.html The sole file requiring changes. Contains the TTS fetch call and the misplaced </div>.

Implementation Plan

Step 1: Fix the TTS fetch URL

Change fetch(BASE_PATH + '/../hero_agent/api/voice/tts' to fetch('/hero_agent/ui/api/voice/tts'

Step 2: Fix the </div> placement

Add </div> after closing col-lg-9 and before {% endblock %}. Remove the orphaned </div> from the end of the file.

Step 3: Clean up spurious blank line

Remove the blank line between if (!data.audio) { and resetReadAloudBtn();.

Step 4: Ensure trailing newline

File must end with a newline character.

Acceptance Criteria

  • The TTS fetch URL is /hero_agent/ui/api/voice/tts (absolute, no BASE_PATH prefix)
  • The <div class="row"> is closed within {% block content %} (before {% endblock %})
  • No orphaned </div> after the final {% endblock %}
  • No spurious blank lines inside the startReadAloud function error-handling logic
  • The file ends with a trailing newline
  • Read Aloud button works when hero_books is embedded at /hero_books/ui/
## Implementation Spec for Issue #77 ### Objective Fix the Read Aloud (TTS) feature in the hero_books page viewer so it works correctly when the application is embedded inside hero_os at `/hero_books/ui/`. The bug has two parts: (1) the TTS fetch URL uses a broken relative path via `BASE_PATH + '/../hero_agent/api/voice/tts'`, and (2) a misplaced closing `</div>` tag causes the `{% endblock %}` directives to sit inside the wrong element. ### Requirements - Replace the TTS fetch URL `BASE_PATH + '/../hero_agent/api/voice/tts'` with the absolute path `/hero_agent/ui/api/voice/tts` so the request resolves correctly regardless of proxy configuration or embedded path prefix. - Move the closing `</div>` for `<div class="row">` so it appears after closing `col-lg-9` and before `{% endblock %}`, rather than after `{% endblock %}` at the very end of the file. - Ensure the file ends with a trailing newline (POSIX convention). - Remove the spurious blank line inside the `if (!data.audio)` block. ### Files to Modify | File | Description | |---|---| | `crates/hero_books_ui/templates/page.html` | The sole file requiring changes. Contains the TTS fetch call and the misplaced `</div>`. | ### Implementation Plan #### Step 1: Fix the TTS fetch URL Change `fetch(BASE_PATH + '/../hero_agent/api/voice/tts'` to `fetch('/hero_agent/ui/api/voice/tts'` #### Step 2: Fix the `</div>` placement Add `</div>` after closing `col-lg-9` and before `{% endblock %}`. Remove the orphaned `</div>` from the end of the file. #### Step 3: Clean up spurious blank line Remove the blank line between `if (!data.audio) {` and `resetReadAloudBtn();`. #### Step 4: Ensure trailing newline File must end with a newline character. ### Acceptance Criteria - [ ] The TTS fetch URL is `/hero_agent/ui/api/voice/tts` (absolute, no BASE_PATH prefix) - [ ] The `<div class="row">` is closed within `{% block content %}` (before `{% endblock %}`) - [ ] No orphaned `</div>` after the final `{% endblock %}` - [ ] No spurious blank lines inside the startReadAloud function error-handling logic - [ ] The file ends with a trailing newline - [ ] Read Aloud button works when hero_books is embedded at `/hero_books/ui/`
Author
Member

Implementation Summary

Changes Made

File modified: crates/hero_books_ui/templates/page.html

  1. Fixed TTS fetch URL: Changed fetch(BASE_PATH + '/../hero_agent/api/voice/tts', ...) to fetch('/hero_agent/ui/api/voice/tts', ...) so the Read Aloud button works correctly when hero_books is embedded behind a proxy at /hero_books/ui/.

  2. Fixed HTML structure: Moved the closing </div> for <div class="row"> to appear before {% endblock %} instead of after it, correcting the HTML nesting within the Jinja template blocks.

  3. Removed spurious blank line: Cleaned up an empty line inside the if (!data.audio) error-handling block.

  4. Added trailing newline: Ensured the file ends with a POSIX-compliant newline character.

Test Results

  • cargo test --release -p hero_books_ui -- passed (compilation and test harness clean)

Notes

  • The fix uses an absolute URL /hero_agent/ui/api/voice/tts instead of BASE_PATH-relative because the TTS endpoint is a cross-service call to hero_agent, not a hero_books-local endpoint.
  • All other fetch calls in the codebase correctly use BASE_PATH for hero_books-local endpoints and are unaffected.
## Implementation Summary ### Changes Made File modified: `crates/hero_books_ui/templates/page.html` 1. **Fixed TTS fetch URL**: Changed `fetch(BASE_PATH + '/../hero_agent/api/voice/tts', ...)` to `fetch('/hero_agent/ui/api/voice/tts', ...)` so the Read Aloud button works correctly when hero_books is embedded behind a proxy at `/hero_books/ui/`. 2. **Fixed HTML structure**: Moved the closing `</div>` for `<div class="row">` to appear before `{% endblock %}` instead of after it, correcting the HTML nesting within the Jinja template blocks. 3. **Removed spurious blank line**: Cleaned up an empty line inside the `if (!data.audio)` error-handling block. 4. **Added trailing newline**: Ensured the file ends with a POSIX-compliant newline character. ### Test Results - `cargo test --release -p hero_books_ui` -- passed (compilation and test harness clean) ### Notes - The fix uses an absolute URL `/hero_agent/ui/api/voice/tts` instead of `BASE_PATH`-relative because the TTS endpoint is a cross-service call to hero_agent, not a hero_books-local endpoint. - All other `fetch` calls in the codebase correctly use `BASE_PATH` for hero_books-local endpoints and are unaffected.
Author
Member

Pull request opened: lhumina_code/hero_books#93

This PR implements the changes discussed in this issue.

Pull request opened: https://forge.ourworld.tf/lhumina_code/hero_books/pulls/93 This PR implements the changes discussed in this issue.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_os#77
No description provided.