Skip to content

Config

YAML company configuration loading and validation.

Schema

schema

Root configuration schema and config-level Pydantic models.

ModelMetadata pydantic-model

Bases: BaseModel

Capability and family/generation metadata for a single model.

Enriched from litellm at discovery and persisted on :class:~synthorg.config.provider_schema.ProviderModelConfig so the matcher can select on real capability data offline.

Attributes:

Name Type Description
supports_tools bool

Model supports function/tool calling. The discovery-time claim (litellm / preset / probe / unknown); the matcher reads it optimistically for unknown sources.

tool_calls_verified bool | None

Runtime-observed tool-calling truth, layered on top of supports_tools. None = never observed (matcher uses the optimistic supports_tools path), True = a real tool call has been seen at runtime, False = repeated runtime tool-call failures proved the model cannot call tools (the matcher treats this as an authoritative hard-fail for requires_tools agents, overriding optimism). Set by the runtime feedback loop (providers.tool_call_feedback); cleared back to None by a manual operator re-enable.

supports_vision bool

Model accepts image inputs.

supports_reasoning bool

Model exposes extended reasoning.

supports_embeddings bool

Model is an embedding model (vector output).

max_output_tokens int | None

Maximum output tokens, when known.

family NotBlankStr | None

Parsed model family (e.g. "example-large").

generation float | None

Parsed generation/recency as a sortable number (e.g. 4.5 for a 4-5 version), higher is newer.

parameter_count int | None

Total model parameters, when known. A coarse size/strength signal the matcher uses to rank quality.

cost_tier int | None

Resource/pricing tier 1-4 (light -> extra heavy). For ollama this is the real per-model usage level scraped from the web page (the API does not expose it); for other providers it is derived from cost/size. Drives cost-aware tiering in the matcher.

release_date date | None

Parsed release date, when derivable from the id.

metadata_source MetadataSource

Provenance of this metadata record.

Config:

  • frozen: True
  • extra: forbid
  • allow_inf_nan: False

Fields:

tool_calls_verified pydantic-field

tool_calls_verified = None

Runtime tool-calling truth: None=unobserved, True=proven, False=runtime-proven-incapable (authoritative matcher hard-fail)

max_output_tokens pydantic-field

max_output_tokens = None

Maximum output tokens, when known

parameter_count pydantic-field

parameter_count = None

Total model parameters, when known (size/strength signal)

cost_tier pydantic-field

cost_tier = None

Resource/pricing tier 1-4 (light -> extra heavy)

family pydantic-field

family = None

Parsed model family (e.g. 'example-large')

generation pydantic-field

generation = None

Sortable generation/recency (higher is newer)

release_date pydantic-field

release_date = None

Parsed release date, when derivable from the id

metadata_source pydantic-field

metadata_source = 'unknown'

Provenance of this metadata record

LocalModelParams pydantic-model

Bases: BaseModel

Per-model launch parameters for local providers.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

  • num_ctx (int | None)
  • num_gpu_layers (int | None)
  • num_threads (int | None)
  • num_batch (int | None)
  • repeat_penalty (float | None)

repeat_penalty pydantic-field

repeat_penalty = None

Repetition penalty

ProviderConfig pydantic-model

Bases: BaseModel

Configuration for an LLM provider.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_auth_fields
  • _validate_unique_model_identifiers

driver pydantic-field

driver = 'litellm'

Driver backend name

litellm_provider pydantic-field

litellm_provider = None

LiteLLM provider identifier for routing (e.g. 'example-provider'). Falls back to the provider name when None.

family pydantic-field

family = None

Provider family for cross-validation grouping (e.g. 'provider-family-a', 'provider-family-b'). When None, the provider name is used as the family.

auth_type pydantic-field

auth_type = AuthType.API_KEY

Authentication type

connection_name pydantic-field

connection_name = None

Reference to a ConnectionCatalog entry. Credentials are resolved from the catalog at runtime; required for API-key auth, which has no embedded credential field.

subscription_token pydantic-field

subscription_token = None

Bearer token for subscription-based auth

tos_accepted_at pydantic-field

tos_accepted_at = None

When subscription ToS was accepted

base_url pydantic-field

base_url = None

Base URL for the provider API

keep_alive pydantic-field

keep_alive = None

Ollama keep_alive: how long the server keeps a model loaded after a request (e.g. '5m', '0' to unload immediately, '-1' to keep forever). Sent only to ollama providers; unset falls back to the driver's bounded default (5m) rather than the ollama server's OLLAMA_KEEP_ALIVE.

vram_guard pydantic-field

vram_guard

VRAM-aware model load/eviction guard for ollama providers (ignored by other providers).

oauth_token_url pydantic-field

oauth_token_url = None

OAuth token endpoint URL

oauth_client_id pydantic-field

oauth_client_id = None

OAuth client identifier

oauth_client_secret pydantic-field

oauth_client_secret = None

OAuth client secret

oauth_scope pydantic-field

oauth_scope = None

OAuth scope string

custom_header_name pydantic-field

custom_header_name = None

Name of custom auth header

custom_header_value pydantic-field

custom_header_value = None

Value of custom auth header

models pydantic-field

models = ()

Available models

retry pydantic-field

retry

Retry configuration for transient errors

rate_limiter pydantic-field

rate_limiter

Client-side rate limiting configuration

subscription pydantic-field

subscription

Subscription and quota configuration

degradation pydantic-field

degradation

Degradation strategy when quota exhausted

defaults pydantic-field

defaults

Last-resort defaults applied when a driver cannot discover per-model metadata (currently used by the LiteLLM driver's fallback max_output_tokens).

preset_name pydantic-field

preset_name = None

Preset used to create this provider (if any)

ProviderModelConfig pydantic-model

Bases: BaseModel

Configuration for a single LLM model within a provider.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

id pydantic-field

id

Model identifier

alias pydantic-field

alias = None

Short alias for routing rules

cost_per_1k_input pydantic-field

cost_per_1k_input = 0.0

Cost per 1k input tokens (base currency)

cost_per_1k_output pydantic-field

cost_per_1k_output = 0.0

Cost per 1k output tokens (base currency)

max_context pydantic-field

max_context = 200000

Maximum context window size in tokens

estimated_latency_ms pydantic-field

estimated_latency_ms = None

Estimated median latency in milliseconds

local_params pydantic-field

local_params = None

Per-model launch parameters for local providers

metadata pydantic-field

metadata

Capability and family/generation metadata (enriched at ingest)

stale pydantic-field

stale = None

Set by the periodic model-refresh service when the id is no longer advertised by its provider; None means current.

RootConfig pydantic-model

Bases: BaseModel

Root company configuration -- the top-level validation target.

Aggregates all sub-configurations into a single frozen model that represents a fully validated company setup.

Attributes:

Name Type Description
company_name NotBlankStr

Company name (required).

company_type CompanyType

Company template type.

departments tuple[Department, ...]

Organizational departments.

agents tuple[AgentConfig, ...]

Agent configurations.

custom_roles tuple[CustomRole, ...]

User-defined custom roles.

config CompanyConfig

Company-wide settings.

budget BudgetConfig

Budget configuration.

communication CommunicationConfig

Communication configuration.

providers dict[str, ProviderConfig]

LLM provider configurations keyed by provider name.

routing RoutingConfig

Model routing configuration.

stakes_routing StakesRoutingConfig

Stakes-aware model routing configuration (strategy discriminator, per-stakes quality floors, coordination nudge).

logging LogConfig | None

Logging configuration (None to use platform defaults).

audit_chain AuditChainConfig

Quantum-safe audit-chain sink configuration (opt-in, disabled by default).

graceful_shutdown GracefulShutdownConfig

Graceful shutdown configuration.

workflow_handoffs tuple[WorkflowHandoff, ...]

Cross-department workflow handoffs.

escalation_paths tuple[EscalationPath, ...]

Cross-department escalation paths.

coordination_metrics CoordinationMetricsConfig

Coordination metrics configuration.

task_assignment TaskAssignmentConfig

Task assignment configuration.

memory CompanyMemoryConfig

Memory backend configuration.

persistence PersistenceConfig

Persistence backend configuration.

cost_tiers CostTiersConfig

Cost tier definitions.

org_memory OrgMemoryConfig

Organizational memory configuration.

api ApiConfig

API server configuration.

sandboxing SandboxingConfig

Sandboxing backend configuration.

mcp MCPConfig

MCP bridge configuration.

security SecurityConfig

Security subsystem configuration.

trust TrustConfig

Progressive trust configuration.

promotion PromotionConfig

Promotion/demotion configuration.

performance PerformanceConfig

Performance tracking configuration (quality judge, CI/LLM weights, trend thresholds).

training TrainingConfig

Training pipeline configuration.

task_engine TaskEngineConfig

Task engine configuration.

recovery EngineRecoveryConfig

Crash recovery strategy selection (fail-reassign by default; checkpoint requires a wired CheckpointRepository from the persistence backend, with tuning from recovery.checkpoint).

queue QueueConfig

Distributed task queue configuration (opt-in, requires a distributed bus backend such as NATS).

coordination CoordinationSectionConfig

Multi-agent coordination configuration.

stagnation StagnationDetectionConfig

Intra-loop stagnation detection selector and sub-configs.

strategy StrategyConfig

Strategy and trendslop mitigation configuration.

knowledge KnowledgeConfig

Knowledge-substrate configuration (on by default; disabled at runtime via the settings-service knowledge.enabled flag).

git_clone GitCloneNetworkPolicy

Git clone SSRF prevention network policy.

backup BackupConfig

Backup and restore configuration.

workflow WorkflowConfig

Workflow type configuration.

notifications NotificationConfig

Notification subsystem configuration.

integrations IntegrationsConfig

External service integrations configuration.

a2a A2AConfig

A2A external gateway configuration (disabled by default).

ontology OntologyConfig

Semantic ontology configuration.

telemetry TelemetryConfig

Anonymous product telemetry configuration (opt-in, disabled by default).

web WebToolsConfig | None

Web tool configuration (None = default web config).

database DatabaseConfig | None

Database tool configuration (None = no database tools).

terminal TerminalConfig | None

Terminal tool configuration (None = default config).

design_tools DesignToolsConfig | None

Design tool configuration (None = disabled).

communication_tools CommunicationToolsConfig | None

Communication tool configuration (None = disabled).

analytics_tools AnalyticsToolsConfig | None

Analytics tool configuration (None = disabled).

tool_disclosure ToolDisclosureConfig

Progressive tool disclosure configuration.

posture PostureConfig

Resolved operating-posture feature flags.

Config:

  • frozen: True
  • allow_inf_nan: False
  • extra: forbid

Fields:

Validators:

  • _validate_unique_agent_names
  • _validate_unique_department_names
  • _validate_milestone_clean_history_windows
  • _validate_queue_requires_distributed_bus
  • _validate_routing_references
  • _validate_degradation_fallback_providers

company_name pydantic-field

company_name

Company name

company_type pydantic-field

company_type = CompanyType.CUSTOM

Company template type

departments pydantic-field

departments = ()

Organizational departments

agents pydantic-field

agents = ()

Agent configurations

custom_roles pydantic-field

custom_roles = ()

User-defined custom roles

config pydantic-field

config

Company-wide settings

budget pydantic-field

budget

Budget configuration

communication pydantic-field

communication

Communication configuration

providers pydantic-field

providers

LLM provider configurations

routing pydantic-field

routing

Model routing configuration

stakes_routing pydantic-field

stakes_routing

Stakes-aware model routing configuration

logging pydantic-field

logging = None

Logging configuration

audit_chain pydantic-field

audit_chain

Quantum-safe audit-chain sink configuration (opt-in)

graceful_shutdown pydantic-field

graceful_shutdown

Graceful shutdown configuration

workflow_handoffs pydantic-field

workflow_handoffs = ()

Cross-department workflow handoffs

escalation_paths pydantic-field

escalation_paths = ()

Cross-department escalation paths

coordination_metrics pydantic-field

coordination_metrics

Coordination metrics configuration

task_assignment pydantic-field

task_assignment

Task assignment configuration

memory pydantic-field

memory

Memory backend configuration

persistence pydantic-field

persistence

Persistence backend configuration

cost_tiers pydantic-field

cost_tiers

Cost tier definitions

org_memory pydantic-field

org_memory

Organizational memory configuration

api pydantic-field

api

API server configuration

sandboxing pydantic-field

sandboxing

Sandboxing backend configuration

mcp pydantic-field

mcp

MCP bridge configuration

security pydantic-field

security

Security subsystem configuration

trust pydantic-field

trust

Progressive trust configuration

promotion pydantic-field

promotion

Promotion/demotion configuration

performance pydantic-field

performance

Performance tracking configuration

training pydantic-field

training

Training pipeline configuration

task_engine pydantic-field

task_engine

Task engine configuration

recovery pydantic-field

recovery

Crash recovery strategy selection (fail-reassign default)

queue pydantic-field

queue

Distributed task queue configuration (opt-in)

coordination pydantic-field

coordination

Multi-agent coordination configuration

compaction pydantic-field

compaction

Context compaction (oldest-turns summarisation) selector

stagnation pydantic-field

stagnation

Intra-loop stagnation detection selector and sub-configs

strategy pydantic-field

strategy

Strategy and trendslop mitigation configuration

knowledge pydantic-field

knowledge

Knowledge-substrate configuration (on by default; disabled at runtime via the settings-service knowledge.enabled flag)

git_clone pydantic-field

git_clone

Git clone SSRF prevention network policy

backup pydantic-field

backup

Backup and restore configuration

workflow pydantic-field

workflow

Workflow type configuration

notifications pydantic-field

notifications

Notification subsystem configuration

integrations pydantic-field

integrations

External service integrations configuration

a2a pydantic-field

a2a

A2A external gateway configuration (disabled by default)

ontology pydantic-field

ontology

Semantic ontology configuration

telemetry pydantic-field

telemetry

Anonymous product telemetry configuration (opt-in)

web pydantic-field

web = None

Web tool configuration (None = default web config)

database pydantic-field

database = None

Database tool configuration (None = no database tools)

terminal pydantic-field

terminal = None

Terminal tool configuration (None = default terminal config)

design_tools pydantic-field

design_tools = None

Design tool configuration (None = disabled)

communication_tools pydantic-field

communication_tools = None

Communication tool configuration (None = disabled)

analytics_tools pydantic-field

analytics_tools = None

Analytics tool configuration (None = disabled)

tool_disclosure pydantic-field

tool_disclosure

Progressive tool disclosure configuration

Loader

loader

YAML configuration loader with layered merging and validation.

discover_config

discover_config()

Auto-discover a configuration file from well-known locations.

Search order:

  1. ./synthorg.yaml
  2. ./config/synthorg.yaml
  3. ~/.synthorg/config.yaml

Returns:

Type Description
Path

Resolved absolute :class:~pathlib.Path to the first file found.

Raises:

Type Description
ConfigFileNotFoundError

If no configuration file is found at any searched location.

Source code in src/synthorg/config/loader.py
def discover_config() -> Path:
    """Auto-discover a configuration file from well-known locations.

    Search order:

    1. ``./synthorg.yaml``
    2. ``./config/synthorg.yaml``
    3. ``~/.synthorg/config.yaml``

    Returns:
        Resolved absolute :class:`~pathlib.Path` to the first file found.

    Raises:
        ConfigFileNotFoundError: If no configuration file is found
            at any searched location.
    """
    candidates = [*_CWD_CONFIG_LOCATIONS, Path.home() / _HOME_CONFIG_RELATIVE]
    logger.debug(
        CONFIG_DISCOVERY_STARTED,
        searched_paths=[str(c) for c in candidates],
    )
    for candidate in candidates:
        if candidate.is_file():
            resolved = candidate.resolve()
            logger.info(CONFIG_DISCOVERY_FOUND, config_path=str(resolved))
            return resolved

    searched = [str(c) for c in candidates]
    msg = "No configuration file found. Searched:\n" + "\n".join(
        f"  - {p}" for p in searched
    )
    logger.warning(
        CONFIG_DISCOVERY_NOT_FOUND,
        searched=searched,
        error_type=ConfigFileNotFoundError.__name__,
    )
    raise ConfigFileNotFoundError(
        msg,
        locations=tuple(ConfigLocation(file_path=p) for p in searched),
    )

load_config

load_config(config_path=None, *, override_paths=())

Load and validate company configuration from YAML file(s).

Each layer deep-merges onto the previous: built-in defaults, primary config, overrides, then env-var substitution.

Parameters:

Name Type Description Default
config_path Path | str | None

Path to the primary config file, or None to auto-discover.

None
override_paths tuple[Path | str, ...]

Additional config files layered on top.

()

Returns:

Type Description
RootConfig

Validated, frozen :class:RootConfig.

Raises:

Type Description
ConfigFileNotFoundError

If any config file does not exist or discovery finds nothing.

ConfigParseError

If any file contains invalid YAML.

ConfigValidationError

If the merged config fails validation.

Source code in src/synthorg/config/loader.py
def load_config(
    config_path: Path | str | None = None,
    *,
    override_paths: tuple[Path | str, ...] = (),
) -> RootConfig:
    """Load and validate company configuration from YAML file(s).

    Each layer deep-merges onto the previous: built-in defaults,
    primary config, overrides, then env-var substitution.

    Args:
        config_path: Path to the primary config file, or ``None``
            to auto-discover.
        override_paths: Additional config files layered on top.

    Returns:
        Validated, frozen :class:`RootConfig`.

    Raises:
        ConfigFileNotFoundError: If any config file does not exist
            or discovery finds nothing.
        ConfigParseError: If any file contains invalid YAML.
        ConfigValidationError: If the merged config fails validation.
    """
    if config_path is None:
        config_path = discover_config()
    config_path = Path(config_path)

    # Start with defaults, merge primary config
    merged = default_config_dict()
    yaml_text = _read_config_text(config_path)
    primary = _parse_yaml_string(yaml_text, str(config_path))
    merged = deep_merge(merged, primary)

    # Apply overrides and env-var substitution
    merged = _load_and_merge_overrides(merged, override_paths)
    merged = _substitute_env_vars(merged, source_file="<merged config>")

    return _finalize_config(merged, yaml_text, config_path, override_paths)

bootstrap_logging

bootstrap_logging(config=None)

Activate the observability pipeline after config is loaded.

Calls :func:~synthorg.observability.configure_logging with config.logging, or sensible defaults if config is None. Should be called once at startup after :func:load_config returns.

Parameters:

Name Type Description Default
config RootConfig | None

Validated root configuration. When None, the logging system uses default settings.

None
Source code in src/synthorg/config/loader.py
def bootstrap_logging(config: RootConfig | None = None) -> None:
    """Activate the observability pipeline after config is loaded.

    Calls :func:`~synthorg.observability.configure_logging` with
    ``config.logging``, or sensible defaults if *config* is ``None``.
    Should be called **once** at startup after :func:`load_config`
    returns.

    Args:
        config: Validated root configuration.  When ``None``, the
            logging system uses default settings.
    """
    from synthorg.observability import configure_logging  # noqa: PLC0415

    log_cfg = config.logging if config is not None else None
    configure_logging(log_cfg)

load_config_from_string

load_config_from_string(yaml_string, *, source_name='<string>')

Load and validate config from a YAML string.

Merges with built-in defaults before validation. Useful for API endpoints and testing.

Parameters:

Name Type Description Default
yaml_string str

Raw YAML content.

required
source_name str

Label used in error messages.

'<string>'

Returns:

Type Description
RootConfig

Validated, frozen :class:RootConfig.

Raises:

Type Description
ConfigParseError

If the YAML is invalid.

ConfigValidationError

If the merged config fails validation.

Source code in src/synthorg/config/loader.py
def load_config_from_string(
    yaml_string: str,
    *,
    source_name: str = "<string>",
) -> RootConfig:
    """Load and validate config from a YAML string.

    Merges with built-in defaults before validation.  Useful for API
    endpoints and testing.

    Args:
        yaml_string: Raw YAML content.
        source_name: Label used in error messages.

    Returns:
        Validated, frozen :class:`RootConfig`.

    Raises:
        ConfigParseError: If the YAML is invalid.
        ConfigValidationError: If the merged config fails validation.
    """
    data = _parse_yaml_string(yaml_string, source_name)
    merged = deep_merge(default_config_dict(), data)
    merged = _substitute_env_vars(merged, source_file=source_name)
    line_map = _build_line_map(yaml_string)
    return _validate_config_dict(
        merged,
        source_file=source_name,
        line_map=line_map,
    )

Defaults

defaults

Built-in default values for company configuration.

default_config_dict

default_config_dict()

Return base-layer configuration defaults as a raw dict.

These defaults serve as the base layer; user-provided YAML values override them during merging. They ensure that every field has a sensible starting value even if omitted from the config file.

Returns:

Type Description
dict[str, object]

Base-layer configuration dictionary.

Source code in src/synthorg/config/defaults.py
def default_config_dict() -> dict[str, object]:
    """Return base-layer configuration defaults as a raw dict.

    These defaults serve as the base layer; user-provided YAML values
    override them during merging.  They ensure that every field has a
    sensible starting value even if omitted from the config file.

    Returns:
        Base-layer configuration dictionary.
    """
    return {
        "company_name": "SynthOrg",
        "company_type": "custom",
        "departments": [],
        "agents": [],
        "custom_roles": [],
        "config": {},
        "budget": {},
        "communication": {},
        "providers": {},
        "routing": {},
        "stakes_routing": {},
        "logging": None,
        "graceful_shutdown": {},
        "workflow_handoffs": [],
        "escalation_paths": [],
        "coordination_metrics": {},
        "task_assignment": {},
        "memory": {},
        "persistence": {},
        "cost_tiers": {},
        "org_memory": {},
        "api": {},
        "sandboxing": {},
        "mcp": {},
        "security": {},
        "trust": {},
        "promotion": {},
        "performance": {},
        "training": {},
        "evolution": {},
        "compaction": {},
        "task_engine": {},
        "recovery": {},
        "queue": {},
        "coordination": {},
        "stagnation": {},
        "strategy": {},
        "git_clone": {},
        "backup": {},
        "workflow": {},
        "notifications": {},
        "integrations": {},
        "a2a": {},
        "ontology": {},
        "knowledge": {},
        "audit_chain": {},
        "telemetry": {},
        "web": None,
        "database": None,
        "terminal": None,
        "design_tools": None,
        "communication_tools": None,
        "analytics_tools": None,
        "tool_disclosure": {},
        "posture": {},
    }

Errors

errors

Custom exception hierarchy for configuration errors.

ConfigLocation dataclass

ConfigLocation(file_path=None, key_path=None, line=None, column=None)

Source location for a configuration error.

Attributes:

Name Type Description
file_path str | None

Path to the configuration file.

key_path str | None

Dot-separated path to the key (e.g. "budget.alerts.warn_at").

line int | None

Line number in the file (1-based).

column int | None

Column number in the file (1-based).

ConfigError

ConfigError(message, locations=())

Bases: DomainError

Base exception for configuration errors.

Attributes:

Name Type Description
message str

Human-readable error description.

locations tuple[ConfigLocation, ...]

Source locations associated with this error.

Source code in src/synthorg/config/errors.py
def __init__(
    self,
    message: str,
    locations: tuple[ConfigLocation, ...] = (),
) -> None:
    self.message = message
    self.locations = locations
    super().__init__(message)

__str__

__str__()

Format error message with source locations.

Returns:

Type Description
str

The message alone when there are no locations, otherwise the

str

message followed by one indented line per source location.

Source code in src/synthorg/config/errors.py
@override
def __str__(self) -> str:
    """Format error message with source locations.

    Returns:
        The message alone when there are no locations, otherwise the
        message followed by one indented line per source location.
    """
    if not self.locations:
        return self.message
    parts = [self.message]
    for loc in self.locations:
        loc_parts: list[str] = []
        if loc.key_path:
            loc_parts.append(f"  {loc.key_path}")
        if loc.file_path:
            if loc.line is not None and loc.column is not None:
                line_info = f" at line {loc.line}, column {loc.column}"
            elif loc.line is not None:
                line_info = f" at line {loc.line}"
            else:
                line_info = ""
            loc_parts.append(f"    in {loc.file_path}{line_info}")
        parts.extend(loc_parts)
    return "\n".join(parts)

ConfigFileNotFoundError

ConfigFileNotFoundError(message, locations=())

Bases: ConfigError

Raised when a configuration file does not exist.

Source code in src/synthorg/config/errors.py
def __init__(
    self,
    message: str,
    locations: tuple[ConfigLocation, ...] = (),
) -> None:
    self.message = message
    self.locations = locations
    super().__init__(message)

ConfigParseError

ConfigParseError(message, locations=())

Bases: ConfigError

Raised when YAML parsing fails.

Source code in src/synthorg/config/errors.py
def __init__(
    self,
    message: str,
    locations: tuple[ConfigLocation, ...] = (),
) -> None:
    self.message = message
    self.locations = locations
    super().__init__(message)

ConfigValidationError

ConfigValidationError(message, locations=(), field_errors=())

Bases: ConfigError

Raised when Pydantic validation fails.

Attributes:

Name Type Description
field_errors tuple[tuple[str, str], ...]

Per-field error messages as (key_path, message) pairs.

Source code in src/synthorg/config/errors.py
def __init__(
    self,
    message: str,
    locations: tuple[ConfigLocation, ...] = (),
    field_errors: tuple[tuple[str, str], ...] = (),
) -> None:
    super().__init__(message, locations)
    self.field_errors = field_errors

__str__

__str__()

Format validation error with per-field details.

Returns:

Type Description
str

The base location-formatted message when there are no field

str

errors, otherwise a header line plus one indented line per

str

(key_path, message) field error.

Source code in src/synthorg/config/errors.py
@override
def __str__(self) -> str:
    """Format validation error with per-field details.

    Returns:
        The base location-formatted message when there are no field
        errors, otherwise a header line plus one indented line per
        ``(key_path, message)`` field error.
    """
    if not self.field_errors:
        return super().__str__()
    parts = [f"{self.message} ({len(self.field_errors)} errors):"]
    loc_by_key: dict[str, ConfigLocation] = {
        loc.key_path: loc for loc in self.locations if loc.key_path
    }
    for key_path, msg in self.field_errors:
        parts.append(f"  {key_path}: {msg}")
        loc = loc_by_key.get(key_path)
        if loc and loc.file_path:
            if loc.line is not None and loc.column is not None:
                line_info = f" at line {loc.line}, column {loc.column}"
            elif loc.line is not None:
                line_info = f" at line {loc.line}"
            else:
                line_info = ""
            parts.append(f"    in {loc.file_path}{line_info}")
    return "\n".join(parts)