Files
weatherreporter/docs/troubleshooting.md

17 KiB

Weatherreporter Troubleshooting

This guide lists recurring failures with likely causes, diagnostics, and safe fixes. See CLI reference, Configuration reference, and Operations guide for normal usage.

weather_api.base_url is required

Symptom: a generation command fails before collecting weather data.

Likely cause: no Weather API base URL is configured.

Diagnostic:

weatherreporter generate daily --config ./config.yml --date 2026-05-29

Safe fix: add weather_api.base_url to the config file, or pass the intended config path with --config.

Relevant docs: Configuration reference.

weather_api.base_url must be an absolute URL

Symptom: config loading fails with a base URL validation error.

Likely cause: weather_api.base_url is missing a scheme or host.

Diagnostic: inspect the configured value in the file passed to --config.

Safe fix: use an absolute URL such as https://weather.api.example.com/.

Relevant docs: Configuration reference.

Invalid Timezone

Symptom: config loading fails with weather_api.timezone context, or a CLI timezone override fails.

Likely cause: weather_api.timezone or --tz is not recognized.

Diagnostic:

weatherreporter generate daily --tz America/Chicago --date 2026-05-29

Safe fix: use an accepted timezone value, such as an IANA timezone name, Chicago, Stl, a US timezone abbreviation, or a UTC offset.

Relevant docs: Configuration reference.

Storm Command Rejects Time Bounds

Symptom: generate storm fails with requires --start, requires --end, or requires --end after --start.

Likely cause: the manual event window is missing or invalid.

Diagnostic:

weatherreporter generate storm --start 2026-05-29T18:00 --end 2026-05-30T06:00

Safe fix: provide both bounds. Use YYYY-MM-DDTHH:MM in the configured timezone, or RFC3339 timestamps with explicit offsets.

Relevant docs: CLI reference.

Weather API Fetch Fails

Symptom: generation fails with fetch /..., an HTTP status, or request context.

Likely cause: the configured Weather API endpoint is unreachable, returned a non-2xx response, or returned an invalid response envelope.

Diagnostic:

weatherreporter generate daily --config ./config.yml --date 2026-05-29

Safe fix: verify weather_api.base_url, network access, and the Weather API service response. The adapter fetches /observations, /conditions/current, /forecast/hourly, /forecast/narrative, /alerts/active, and /discussion.

Relevant docs: Configuration reference.

Hourly Forecast Is Missing

Symptom: generation fails with hourly forecast context, such as missing hourly data or an hourly forecast containing no periods.

Likely cause: hourly forecast data is required for generated reports.

Diagnostic: check the Weather API response for /forecast/hourly.

Safe fix: restore hourly forecast data at the Weather API. Missing-source policy cannot make hourly optional.

Relevant docs: Configuration reference, Operations guide.

Source Warnings Appear

Symptom: generation succeeds, but metadata or inspect sources shows source warnings.

Likely cause: an optional source was missing or malformed under a warning missing-source policy.

Diagnostic:

weatherreporter inspect sources RUN_ID
weatherreporter inspect metadata RUN_ID

Safe fix: inspect the warning source, code, message, and endpoint. Fix the upstream optional source, or intentionally change the relevant missing_source policy.

Relevant docs: Configuration reference, Operations guide.

scriptorium Is Not Found Or Cannot Start

Symptom: generation fails with run scriptorium render or run scriptorium and an executable or OS error.

Likely cause: the configured Scriptorium binary is unavailable or not executable.

Diagnostic: check scriptorium.binary in config and run the same binary outside weatherreporter.

Safe fix: install Scriptorium, update scriptorium.binary, or fix executable permissions.

Relevant docs: Configuration reference, Scriptorium integration.

Render Preflight Fails

Symptom: generation fails with scriptorium render exited with code ....

Likely cause: Scriptorium rejected the prompt, config, profile, or data_package input before report generation.

Diagnostic:

weatherreporter inspect metadata RUN_ID
weatherreporter inspect data-package RUN_ID

Then read the preflight path from metadata. It contains captured stdout, stderr, exit code, and command.

Safe fix: fix the Scriptorium configuration, prompt ID, profile, or data package input indicated by stderr.

Relevant docs: Operations guide, Scriptorium integration.

Scriptorium Run Fails

Symptom: generation fails with scriptorium run exited with code ....

Likely cause: Scriptorium failed during report generation or validation.

Diagnostic:

weatherreporter inspect metadata RUN_ID
weatherreporter inspect data-package RUN_ID

If metadata includes a rendered report path, inspect that report as well. A nonzero run can still leave a managed report artifact.

Safe fix: use the captured stderr and data package to fix the Scriptorium prompt, profile, model configuration, or validation issue.

Relevant docs: Operations guide, Scriptorium integration.

Generated Text Validation Fails

Symptom: Daily, Today, Tomorrow, or Hourly generation fails with generated-text decode, unknown-field, required-field, or multiple-JSON-values context.

Likely cause: Scriptorium wrote structured JSON that does not match the GeneratedText contract for the selected report.

Diagnostic:

weatherreporter inspect metadata RUN_ID

Then inspect the generated-text raw path recorded in metadata, if present.

Safe fix: update the Scriptorium prompt or schema configuration so the prompt writes the expected structured JSON for the report.

Relevant docs: Operations guide, Generated Text internals, Scriptorium integration.

Template Rendering Fails

Symptom: Daily, Today, Tomorrow, or Hourly generation fails with report template parsing or execution context after generated text validation succeeds.

Likely cause: an embedded template references a missing context field or receives a value shape that does not match its typed render context.

Diagnostic:

weatherreporter inspect metadata RUN_ID

If metadata records generated-text and render-context paths, inspect those artifacts along with the template named by the report definition.

Safe fix: update the embedded template or render-context builder so the template uses the implemented typed context.

Relevant docs: Report Templates, Report Template internals.

Batch Command Returns Nonzero

Symptom: run morning or run evening returns nonzero.

Likely cause: weather collection failed before planning, or at least one planned report failed after planning succeeded, or every report succeeded but the top-level batch distributor notification failed.

Diagnostic: if stdout contains a JSON summary, inspect each failed report item and the top-level notification object. Stderr includes one batchNotification line when batch notification is attempted, skipped, or fails. If no summary was emitted, inspect the command error; configuration, Weather API collection, or batch validation failed before any report artifacts were created.

Safe fix: for collection failures, fix the configuration or upstream Weather API availability and rerun the batch. For report failures, use the failed report's artifact paths from the summary, then inspect metadata, sources, module snapshot, and data package for that RunID. For a batch notification failure, inspect the notification artifact path from the top-level notification.path.

Relevant docs: CLI reference, Operations guide.

Batch Upload Skipped

Symptom: a batch JSON summary contains "notification":{"status":"skipped","reason":"one or more reports failed"}.

Likely cause: at least one planned report failed, so weatherreporter did not call distributor for the batch.

Diagnostic: inspect the failed report items in the batch JSON summary and the matching stderr report lines. A skipped batch notification has no distributor run ID and no notification artifact path.

Safe fix: fix the report-generation failure first, then rerun the batch. The batch upload is all-or-nothing.

Relevant docs: Operations guide.

Batch Upload Fails

Symptom: every report item in a batch summary is succeeded, but the batch returns nonzero and the top-level notification has status: "failed".

Likely cause: the distributor upload was rejected, the distributor service was unavailable, status polling reached a terminal distributor failure, or weatherreporter rejected the batch file mapping before upload.

Diagnostic: inspect notification.error, notification.pipelineId, notification.bundleId, notification.idempotencyKey, and notification.path in stdout. Then inspect the notification artifact; it records included report source paths, bundle paths, upload status, distributor run status, status lookup error, and raw status report JSON when available.

Safe fix: fix the endpoint, token, distributor pipeline, batch identity templates, or report path templates indicated by the error, then rerun the batch. Individual report artifacts from the failed batch notification remain available and do not need to be regenerated for diagnosis.

Relevant docs: Configuration reference, Operations guide.

Duplicate Batch Bundle Path

Symptom: a batch returns nonzero with duplicate bundle path context before a distributor run ID is accepted.

Likely cause: report-specific distributor path templates rendered the same bundle-relative path for two included reports in the same batch.

Diagnostic: inspect the error in stdout or stderr. The validation error includes the duplicate bundle path plus the report IDs, RunIDs, and managed source paths involved.

Safe fix: configure a per-report distributor path override so every report in a batch renders a unique path. Include values such as {artifact_group}, {valid_start_date}, {batch_output_name}, or {run_id} when needed.

Relevant docs: Configuration reference, Operations guide.

Distributor Source Conflict

Symptom: distributor accepts or rejects an upload with conflict context for a source, destination, digest, or idempotency key.

Likely cause: the rendered bundle ID or idempotency key does not match the intended producer identity. A bundle ID identifies the logical source stream; an idempotency key identifies a retry of the same upload request.

Diagnostic: inspect the report notification artifact linked from metadata or the batch notification artifact linked from the top-level notification path. Compare the rendered pipeline ID, bundle ID, idempotency key, included source paths, and bundle paths with notify.distributor.* templates and distributor pipeline state.

Safe fix: keep bundle ID templates stable for the source stream that should be updated, and keep idempotency keys stable only for retries of the same generated content. Do not reuse one idempotency key for different report or batch content.

Relevant docs: Operations guide, Distributor adapter internals.

Invalid Secrets Directory

Symptom: config loading fails with read secrets directory, secret file, or environment variable name context.

Likely cause: secrets.directory points to a missing directory or contains an invalid entry. Secret entries must be regular files directly under the configured directory, and file basenames must match [A-Za-z_][A-Za-z0-9_]*.

Diagnostic: list the configured directory and inspect entry names and file types. Do not print secret file contents.

Safe fix: create the directory, remove subdirectories or symlinks, fix invalid filenames, and ensure the weatherreporter process can read each secret file.

Relevant docs: Configuration reference.

Distributor Token Is Missing

Symptom: notification fails with a message that the distributor token environment variable is not set.

Likely cause: notify.distributor.enabled is true, but the environment variable named by notify.distributor.token_env was not populated directly or through secrets.directory.

Diagnostic: check notify.distributor.token_env, then verify a matching secret file exists under secrets.directory or that the process environment includes the variable. Do not print the token value.

Safe fix: create a readable secret file whose basename matches token_env, or set the environment variable through the service manager.

Relevant docs: Configuration reference, Operations guide.

Distributor Upload Conflict

Symptom: notification fails with idempotency conflict context.

Likely cause: the same idempotency key was reused for different bundle content within the same distributor token and pipeline. By default the bundle ID is a stable report-stream identity and the idempotency key appends RunID.

Diagnostic: inspect the failed batch JSON or stderr line for pipeline, bundle, and idempotency context. For batch commands, use the top-level notification object rather than per-report notification fields. Compare the configured templates with the report RunID or batch RunID and report path.

Also inspect the notification artifact linked from metadata or from the top-level batch notification path. It records the rendered pipeline ID, bundle ID, idempotency key, upload result, distributor run status, status error, and raw run report JSON when available.

Safe fix: keep idempotency templates stable for retries of the same generated report, but do not reuse the same rendered key for different generated report content.

Relevant docs: Operations guide, Distributor adapter internals.

Distributor Upload Rejected

Symptom: notification fails with distributor upload rejection, HTTP status, or bundle validation context.

Likely cause: the distributor endpoint rejected the token, pipeline ID, bundle ID, idempotency key, source file, or one of the rendered bundle paths.

Diagnostic: inspect stdout JSON or stderr status lines for notificationError or the top-level batch notification error. Confirm notify.distributor.endpoint, notify.distributor.pipeline_id_template, report-specific distributor paths, and token configuration. Token values are redacted from weatherreporter errors.

If the upload was accepted but destination output did not change, inspect the notification artifact's runStatus.report. Distributor actions such as replace_older, skip_same, skip_destination_newer, or failed explain how the destination handled the uploaded bundle.

Safe fix: fix the endpoint, token, templates, or distributor-side upload configuration. The weatherreporter upload source is the managed Markdown report, not --out or --out-dir copies.

Relevant docs: Configuration reference, Operations guide, Distributor adapter internals.

Distributor Unavailable

Symptom: notification fails with network, timeout, or service unavailable context.

Likely cause: the configured distributor endpoint is unreachable, slow, or temporarily unavailable.

Diagnostic: check network access from the weatherreporter host to notify.distributor.endpoint. For batch runs, inspect the top-level notification object and the artifact linked by notification.path.

Safe fix: restore distributor service availability and rerun the affected report or batch. Stable idempotency keys make retrying the same generated report safe unless the distributor reports a conflict.

Relevant docs: Operations guide.

Unknown RunID

Symptom: an inspect command fails with metadata for run id ... was not found.

Likely cause: the RunID is mistyped or the command is reading a different workspace.

Diagnostic:

weatherreporter inspect reports --config ./config.yml --limit 20

Safe fix: copy a RunID from inspect reports, or use the same --config and workspace that generated the report.

Relevant docs: Operations guide.

Workspace Path Error

Symptom: startup or inspection fails with workspace path validation or filesystem read/write context.

Likely cause: a workspace subdirectory is absolute, escapes workspace.root, or the process cannot read or write the configured path.

Diagnostic: review workspace.root, workspace.snapshots_dir, workspace.reports_dir, workspace.data_packages_dir, and workspace.preflight_dir.

Safe fix: keep workspace subdirectories relative to workspace.root, and grant the process appropriate filesystem permissions.

Relevant docs: Configuration reference, Operations guide.