Troubleshooting

Common issues and solutions when working with meridian-tools.

Installation issues

meridian-tools --help fails with ImportError

Cause: The package is not installed in the active environment, or Meridian is missing.

Fix:

pip install -e ".[dev]"

If Meridian is not installed:

pip install "google-meridian[schema]==1.5.3"

RuntimeError: Saving meridian_model.binpb requires Meridian schema support

Cause: Meridian was installed without the [schema] extra.

Fix:

pip install "google-meridian[schema]==1.5.3"

RuntimeError: Saving PNG plots requires vl-convert-python

Cause: The vl-convert-python package is not installed or not importable.

Fix:

pip install "vl-convert-python>=1.7.0,<2"

Configuration errors

pydantic.ValidationError: Extra inputs are not permitted

Cause: The YAML file contains a key that is not part of the schema. This is often a typo.

Fix: Check the key name against the YAML schema reference. All config models use extra="forbid", so unexpected keys are always rejected.

Legacy holdout_size shorthand is no longer supported

Cause: The YAML has validation.holdout_size without an explicit validation.strategy.

Fix: Add strategy: blocked_tail:

validation:
  strategy: blocked_tail
  holdout_size: 8

validation.strategy: blocked_tail does not accept rolling-origin parameters

Cause: The YAML mixes blocked_tail strategy with initial_train_size, test_size, or other rolling-origin fields.

Fix: Choose one strategy. Use blocked_tail with holdout_size only, or rolling_origin with its own parameters.

optimisation.end_date must be on or after optimisation.start_date

Cause: The dates in the optimisation section are reversed.

Fix: Ensure start_date precedes end_date:

optimisation:
  start_date: "2025-01-01"
  end_date: "2025-12-31"

response_curves.spend_multipliers must not be empty

Cause: The spend_multipliers list is empty or missing.

Fix: Provide at least one non-negative value:

response_curves:
  spend_multipliers: [0.0, 0.5, 1.0, 1.5, 2.0]

Pipeline execution errors

Dependency preflight failure

Cause: A required wrapper dependency check failed before config/data preflight or run-directory creation.

Common triggers:

  • google-meridian[schema] support is unavailable
  • exports.export_plots: true is set but vl-convert-python PNG support is unavailable

Fix: Install or repair the missing runtime dependency first, then rerun.

ConfigPreflightError

Cause: meridian-tools found a wrapper-owned config or input-data issue before run-directory creation.

Common triggers:

  • data.path resolves to a missing file or a directory
  • the CSV header row cannot be read
  • the header is empty or contains blank cells
  • an authored column name does not appear in the header exactly
  • a supported media/RF family is only half-authored

Fix: Correct the authored YAML or the input CSV first, then rerun. Header matching is exact and case-sensitive in Phase 10.

ValidationExecutionContractError

Cause: The requested single-run execution path is incompatible with the authored validation setup.

Common triggers:

  • you tried to run a rolling_origin config directly from the CLI or run_pipeline(...)
  • you passed PipelineRunConfig.validation_spec while the YAML already authors model_spec.kwargs.holdout_id

Fix: For rolling_origin, build a validation plan and execute one concrete split at a time through the Python API. For authored holdouts, either keep the YAML-authored holdout_id path or remove it before supplying a runtime validation_spec. See the validation guide for the full workflow.

ModelSelectionError with reason_code: holdout_fit_unsupported

Cause: LOO/WAIC was requested for a model fitted with a holdout mask.

Not a bug. Model selection is only available for full-sample fits. The pipeline records the incompatibility in model_selection_status.json and continues. See the model selection guide.

ModelSelectionError with reason_code: meridian_internal_seam_incompatible

Cause: The installed Meridian version does not expose the internal reconstruction methods needed for log-likelihood computation.

Fix: Check the Meridian version. This package requires google-meridian[schema]==1.5.3. If you recently upgraded Meridian, the private reconstruction seams may have changed. Check the Meridian integration notes.

Run fails mid-pipeline

If a run fails after the dated run directory already exists, meridian-tools raises PipelineRunFailure. The CLI and runme.py print the concrete failed run directory, manifest path, and stage name when available. The original exception is preserved as __cause__, so --traceback still shows the underlying failure.

The manifest is written to disk after each stage. If a run fails, the run_manifest.json is left on disk and marked failed. You can inspect it to determine which stage failed:

cat runs/my-project_*/run_manifest.json | python -m json.tool

Look at the stages array. A failed stage is recorded with status: "failed" and an error message.

Validation errors

time_index must be strictly increasing with no duplicate values

Cause: The time column in your data contains duplicates or is not sorted.

Fix: Ensure your CSV data has unique, monotonically increasing time values. For geo-panel data, the time column should be unique per time period (not per geo × time combination — the function expects the deduplicated time axis).

rolling_origin must yield at least two splits

Cause: The combination of initial_train_size, test_size, and data length does not produce enough splits.

Fix: Either reduce initial_train_size, reduce test_size, or use blocked_tail instead for shorter series.

holdout_size must be smaller than the time axis

Cause: The holdout size is greater than or equal to the number of time periods.

Fix: Reduce holdout_size to leave at least one training period.

Lifecycle errors

LifecycleError when loading a run record

Cause: The run manifest is missing required entries, references a file that does not exist, or has a malformed JSON structure.

Fix: Check that the run directory was not manually modified. Required artefacts are config.source.yaml and config.resolved.yaml. diagnostics_bundle.json is optional for loading but required for new runs.

Path traversal rejection

Cause: An artefact path in the manifest resolves outside the run directory.

Not fixable by editing the manifest. This is a security check. The manifest was likely corrupted or manually edited with an invalid path.

Performance issues

Pipeline takes very long

MCMC sampling (the 20_model_fit stage) dominates wall-clock time. The meridian-tools orchestration layer adds negligible overhead.

To speed up exploratory runs:

fit:
  n_chains: 2       # Fewer chains (minimum 1)
  n_adapt: 200      # Fewer adaptation steps
  n_burnin: 200     # Fewer burn-in steps
  n_keep: 500       # Fewer kept samples

For production runs, use the defaults or increase these values for better posterior quality.

Out-of-memory during model selection

Log-likelihood reconstruction loads the full posterior into memory and creates a temporary copy of the InferenceData. For large models, this can double memory usage temporarily.

Mitigation: Reduce n_keep or n_chains if memory is constrained.

Warnings

ArviZ Pareto k warnings

Estimated shape parameter of Pareto distribution is greater than 0.7 ...

This means the LOO approximation is unreliable for some observations. Check the pointwise pareto_k values in loo_pointwise.csv. Values above 0.7 indicate influential observations.

Meridian national model auto-zeroing warnings

Hierarchical distribution parameters must be deterministically zero for
national models. eta_orf has been automatically set to Deterministic(0).

This is expected for national (non-geo) models. Meridian automatically zeros out geo-level hierarchical parameters. The warning is informational.

TensorFlow deprecation warnings

These come from TensorFlow and Meridian internals. meridian-tools groups and deduplicates them in the terminal output to reduce noise. They do not indicate a problem with your run.