Troubleshooting maps observable StoryMatrix failures to confirmed causes, operator actions, and tracked blocker anchors.

🚨 Live blockers

The focused contracts B1 and B13–B17 are resolved at their named boundaries. B2–B12, the flaky suite, structural work, and evidence-blocked runs remain open; this table keeps their actionable symptoms.

IDObservable symptomCauseFixTracking
B1Minimal startup previously imported unavailable SFX extrasLocalSFXAdapter now defers optional imports and resource probing (src/storymatrix/infrastructure/adapters/sfx/local.py).No workaround is required for import-safe startup; exercise local features only with their optional dependencies.Resolved — B1
B2NameError: name 'llm' is not defined in the legacy story crew_create_legacy_story_crew_inline() tests and assigns llm although its parameter is llm_service (src/storymatrix/crew/crew.py).Use the function’s injected LLM service consistently and add a regression test for the fallback.B2
B3Timeline generation silently falls back to deterministic outputLLMAgenticTimelineAdapter calls logger in response parsing without defining it; fallback handling absorbs the resulting exception (src/storymatrix/infrastructure/adapters/timeline/llm_agentic_timeline_adapter.py).Define the module logger, then exercise the agentic path and assert that a valid agentic response reaches the timeline.B3
B4TypeError: Can't instantiate abstract class MockImageServiceMockImageService implements generate_image but not the interface’s generate_image_for_scene method (src/storymatrix/infrastructure/services/image/mock_image_service.py, src/storymatrix/application/interfaces/services.py).Implement the missing abstract operation and verify the local-only container branch.B4
B5BadRequestError: LLM Provider NOT provided with mock-provider/mock-responseThe image-prompt crew sends the mock sentinel string to LiteLLM instead of using a mock service (src/storymatrix/crew/image_prompt_crew.py, 01_ERROR.ini).Route mock mode to a local/mock LLM implementation or provide a valid provider/model pair without making a paid call.B5
B6AttributeError: 'coroutine' object has no attribute 'id' in media repository testsFileSystemMediaAssetRepository.save is async while callers still treat it as synchronous (src/storymatrix/infrastructure/repositories/file_media_asset_repository.py).Await repository saves at every caller and retain async boundaries through the service layer.B6
B7ValidationError: 2 validation errors for StoryData at golden-path setupStoryData.background_music is required, while the golden fixture omits it (src/storymatrix/crew/schemas.py, tests/integration/test_golden_path.py).Add the field to the fixture or establish an explicit schema default, then refresh the snapshot only after the contract is intentional.B7
B8AttributeError: 'str' object has no attribute 'exists' during container-wiring setupThe integration fixture supplies a string where a Path is required (tests/integration/test_container_wiring.py).Construct a pathlib.Path in the fixture and keep path types at the container boundary.B8
B9Runtime annotation resolution raises NameError for sessionmakerSQLiteContentRepository annotates sessionmaker without importing it; postponed annotations hide the defect until resolution (src/storymatrix/infrastructure/repositories/sqlite_content_repository.py).Import sessionmaker from SQLAlchemy in the repository module and resolve annotations in a focused test.B9
B10Ruff reports 18 F821 errors in src/Undefined runtime names include the live llm, logger, and sessionmaker defects plus unresolved annotation types (src/, Ruff F821 output).Resolve every undefined name or import, then run the targeted F821 check before broad linting.B10
B11Repository status shows spent scripts, raw logs, and untracked support filesRoot debris includes fix_repo.py, test_reproduce.py, 01_ERROR.ini, .claude/, and scripts/pack-audit-zip.sh (git status evidence).Classify each artifact, preserve incident evidence where needed, and remove or archive disposable debris through the repository’s normal review process.B11
B12Operators read a stale output-root instructionAGENTS.md disagrees with AppSettings.output_dir, while src/storymatrix/config/models.py and storymatrix_config.yaml select out.Follow the code contract out/ and correct the stale instruction in the owning documentation.B12
B13Web startup previously lacked typed title/theme/reload settingsWebSettings now declares the fields consumed by ui.run(...) (src/storymatrix/config/models.py, src/storymatrix/interfaces/web/main.py).Use the typed settings; full browser workflow remains separately scoped.Resolved — B13
B14API dependencies previously rejected every requestDependencies now read config.services.api; focused health/metrics dispatch reaches handlers (src/storymatrix/interfaces/api/main.py).Use the repaired API contract; broader generation remains separately scoped.Resolved — B14
B15CLI mode flags previously lost to YAMLTyped CLI overrides now apply after YAML and environment values (src/storymatrix/cli/main.py, src/storymatrix/config/config.py).Use explicit --offline/--low-resource; focused cost-safety evidence is complete.Resolved — B15
B16Loader previously printed provider strategy to stdoutThe unconditional print was removed (src/storymatrix/config/config.py).No action; unrelated suite/lint noise remains open.Resolved — B16
B17Status route previously required story_id and returned the wrong model fieldHandler now accepts job_id only and returns StoryStatusResponse(job_id, status, result) (src/storymatrix/interfaces/api/main.py).Poll by job ID; focused pending/ready states are schema-valid without a broker.Resolved — B17

🧯 Historical incidents and resolved failures

The records below come from the raw error log and the incident archive; they are separate from the live blocker list.

StateSymptomRoot causeOperator action / fixEvidence
LiveImage-prompt generation emits BadRequestError: LLM Provider NOT provided for mock-provider/mock-response.LiteLLM receives a sentinel model string without a provider.Apply B5’s mock routing fix; do not interpret deterministic output as a successful image-prompt crew run.01_ERROR.ini, src/storymatrix/crew/image_prompt_crew.py
ResolvedMontage input serialization rejects NarrationSegment as not JSON serializable.Montage serialization passes a Pydantic segment object directly to JSON.ffmpeg_montage.py now calls model_dump(mode="json"); treat any recurrence as regression evidence.01_ERROR.ini, src/storymatrix/infrastructure/services/ffmpeg_montage.py
ResolvedGeneration appears frozen while a parent process remains visible.A child process crashes and the parent shell masks the failure; an exception handler also references an undefined start_time.Inspect child logs and process trees; the 2025-09-30 remediation adds four-layer timeout prevention and heartbeat logging.WALL-OF-FAME.md (2025-09-30 05:30 UTC+2)
ResolvedZombie-process recovery still lacks operator visibility.Stage timing and heartbeat variables use incorrect scope (start_time and current_time), and audio production omits a return.Use the heartbeat cadence and corrected variable scope from the 2025-09-30 05:55 UTC+2 remediation.WALL-OF-FAME.md (2025-09-30 05:55 UTC+2)
ResolvedSFX orchestration cancels unpredictably and local-only runs lack dependable timeout behavior.Cancellation handling and timeout paths lack explicit orchestration controls.Use the hardened cancellation and timeout paths documented by the 2025-08-27 remediation; inspect provider logs when a request stops.WALL-OF-FAME.md (2025-08-27)
ResolvedAudio montage loses SFX or music through enum serialization and FFmpeg path handling.Audio segment values and filesystem paths do not reach montage inputs in the expected serialized form.Keep enum serialization and Path handling covered by montage tests; the 2025-07-29 and 2025-09-12 remediations record the fixes.WALL-OF-FAME.md (2025-07-29, 2025-09-12)
Resolvedname 'generate_character_id' is not defined, 100% story-generation failure, and the pipeline stops at stage 2/3 (2025-10-12 02:28–03:53 UTC+2).A refactor extracts the character-ID utility but omits imports in audio production, character mapping, and crew transformer services.Add the three missing imports; the incident record reports 11/11 integration tests and restored generation after a 38-minute response.WALL-OF-FAME.md (2025-10-12 02:28–03:53 UTC+2)
EnvironmentalLocal generation fails because a provider dependency or model is unavailable.The selected install profile does not contain the local ML dependency, or the local asset/model path is absent.Choose uv sync --extra local, verify configured asset paths, and set APP__DEV_LOCAL_ONLY=true for a no-cost path.pyproject.toml, src/storymatrix/config/models.py

The archive also records a persistent story-data validation failure during the 2025 stabilization work; the current schema and fixtures remain covered by B7 rather than treating the old prose as a current pass claim.

🧩 Domain exceptions

The domain exception hierarchy identifies the operator’s response class (src/storymatrix/domain/exceptions.py).

ExceptionRaised whenOperator response
ConfigurationErrorConfiguration is invalid or missing.Inspect effective settings, environment names, YAML structure, and required credentials without publishing secret values.
EntityNotFoundErrorA repository lookup cannot find the requested entity ID and type.Confirm the ID, database selection, and preceding create/commit operation.
DomainErrorDomain logic rejects an invariant or operation.Preserve the message and details, then correct the invalid domain input or state transition.
RepositoryErrorRepository work fails; the exception records an optional operation and details.Check the database or filesystem backend, operation name, and path permissions, then retry only after the cause is clear.
ValidationErrorInput data fails validation checks.Read the field-level validation message and correct the request, fixture, or schema contract.
StoryGenerationErrorStory production fails at the generation boundary.Inspect stage logs and checkpoint state before deciding whether to resume or restart.
LLMGenerationErrorAn LLM interaction fails.Check provider selection, model configuration, request payload, and local-only routing.
LLMTimeoutErrorAn LLM request exceeds its timeout.Confirm endpoint reachability and timeout settings, then use a local or fallback provider.
LLMInvalidRequestErrorAn LLM provider rejects the request as invalid.Inspect model name and request shape; correct configuration before retrying.
LLMRateLimitErrorAn LLM provider reports a rate limit.Stop repeated retries, reduce concurrency, and wait for the provider window or switch to local mode.
LLMServiceUnavailableErrorAn LLM provider is unavailable.Check provider status and network policy, then select a local/mock route when cost control applies.
ExternalServiceErrorAn external service call fails; the exception records service name and optional details.Identify the named service, inspect credentials and endpoint configuration, and use a configured fallback.

🧭 Escalation sequence

  1. Capture the exact symptom, stage, provider, and request mode from the console and app_debug.log.
  2. Check the matching blocker anchor before changing configuration.
  3. Preserve checkpoint.json and artifact metadata when a run fails; resume only after the cause is understood.
  4. Set APP__DEV_LOCAL_ONLY=true before exploratory retries that must not call paid providers.
  5. Record a new reproducible symptom with its source path and date; do not convert an unverified historical claim into a current status.