Skip to main content
Applies to:
  • Plan:
  • Deployment:

Summary

Issue: The error Mismatch between expected span parent object type project_logs and provided type experiment occurs when mixing logger and experiment contexts in the same trace hierarchy. Cause: init_logger() creates project_logs spans while braintrust.init() creates experiment spans — these cannot be mixed as parent/child spans in the same trace. Resolution: Use separate instances for logging and experiments, ensuring child spans match their parent’s container type.

Why this happens with multiple projects

When using a single project with set_current=True, Braintrust uses one global context for all spans. The error occurs with multiple projects because:
  • Multiple loggers require set_current=False to prevent overwriting each other’s state
  • Without a global context, spans need explicit parent-child relationships
  • Parent spans from init_logger() export as project_logs type
  • Child spans from experiments expect experiment type parents
  • The type mismatch triggers the assertion error

Resolution steps

If you only need logging

Step 1: Initialize with login

import braintrust

braintrust.login()

logger_a = braintrust.init_logger(project="project-a", set_current=False)
logger_b = braintrust.init_logger(project="project-b", set_current=False)

Step 2: Use logger instances directly

with logger_a.start_span(name="request") as span:
    span.log(input="Hello", output="Response")

braintrust.flush()

If you only need experiments

Step 1: Use init for experiments

import braintrust

braintrust.login()

exp_a = braintrust.init(project="project-a", experiment="my-experiment", set_current=False)
exp_b = braintrust.init(project="project-b", experiment="my-experiment", set_current=False)

Step 2: Create experiment spans

with exp_a.start_span(name="eval") as span:
    span.log(input="What is 2+2?", output="4", expected="4", scores={"exact_match": 1.0})

braintrust.flush()

If you need both logging and experiments

Step 1: Maintain separate instances per context type

braintrust.login()

# For production logging
log_instance = braintrust.init_logger(project="project-a", set_current=False)

# For experiment runs  
exp_instance = braintrust.init(project="project-a", experiment="my-experiment", set_current=False)

Step 2: Route to correct instance at runtime

def get_instance(is_experiment: bool):
    return exp_instance if is_experiment else log_instance
Warning: BraintrustCallbackHandler attaches to the active parent context. If the parent originated from init_logger() but you’re inside an experiment trace, the mismatch error will occur.

Alternative: Use single logger only

If experiment tracking isn’t required, use one init_logger() with set_current=True:
braintrust.login()
braintrust.init_logger(project="project-a", set_current=True)