Skip to content

fix(propagation): coerce non-string metadata values to string#1680

Open
aryxnn wants to merge 4 commits into
langfuse:mainfrom
aryxnn:fix-metadata-coercion
Open

fix(propagation): coerce non-string metadata values to string#1680
aryxnn wants to merge 4 commits into
langfuse:mainfrom
aryxnn:fix-metadata-coercion

Conversation

@aryxnn
Copy link
Copy Markdown

@aryxnn aryxnn commented May 31, 2026

Allows propagate_attributes to accept and automatically convert non-string metadata values (int, float, bool) to strings instead of silently dropping them. This resolves tracing compatibility issues with LangGraph integrations.

What does this PR do?

PR title must follow Conventional Commits, for example feat: add dataset scoring helper or fix(openai): preserve trace context.

Fixes #

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Refactor
  • Documentation update
  • Tooling, CI, or repo maintenance

Verification

List the main commands you ran:

Checklist

  • I self-reviewed the diff using code_review.md.
  • I added or updated tests for behavior changes.
  • I updated docs, examples, or .env.template if needed.
  • I did not hand-edit generated files; if generated files changed, I used the upstream regeneration path.
  • I did not commit secrets or credentials.

Greptile Summary

This PR allows propagate_attributes to accept non-string metadata values (int, float, bool, and any other type) and automatically coerces them to strings via str() rather than silently dropping them. The change fixes tracing compatibility with LangGraph integrations that inject non-string metadata.

  • The type signature of the metadata parameter (and the internal _propagate_attributes equivalent) is widened from Dict[str, str] to Dict[str, Any], and None values in the metadata dict are now explicitly skipped before the string-length validation step.
  • A new unit test covers coercion of int, float, and bool values, verifying the resulting string representations in child spans.

Confidence Score: 4/5

The change is small and well-targeted; the coercion path is safe for the common cases and the existing validation guard (200-char limit) still applies after coercion.

The core logic is correct and the new test exercises int, float, and bool. The main open question is whether Python-style 'True'/'False' is the right representation for booleans — downstream consumers expecting JSON-style 'true'/'false' would silently get wrong values. The docstring also still describes the old 'must be strings' constraint, which could confuse users reading the API docs.

langfuse/_client/propagation.py — specifically the boolean coercion representation and the outdated docstring note.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["propagate_attributes called with metadata dict"] --> B{metadata is None?}
    B -- Yes --> Z[Skip metadata]
    B -- No --> C[Iterate over key-value pairs]
    C --> D{value is None?}
    D -- Yes --> C
    D -- No --> E{value is a str?}
    E -- Yes --> F[string_value = value]
    E -- No --> G["string_value = str(value)"]
    F --> H{len <= 200 chars?}
    G --> H
    H -- No --> I[Log warning and drop key]
    H -- Yes --> J[Add to validated_metadata]
    J --> C
    J --> K[Set propagated OTel attribute]
Loading
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
langfuse/_client/propagation.py:206-208
The docstring still states that metadata values "must be strings ≤200 characters", but this PR explicitly relaxes that constraint by auto-coercing non-string values. Leaving the note unchanged will mislead users who read the docs.

```suggestion
        - **Validation**: All attribute values (user_id, session_id, metadata values)
          must be ≤200 characters. Non-string metadata values (int, float, bool, etc.)
          are automatically coerced to their string representation. Values exceeding
          200 characters will be dropped with a warning logged.
```

### Issue 2 of 3
langfuse/_client/propagation.py:289
`bool` in Python coerces to `"True"`/`"False"` (capital first letter) rather than the JSON-conventional `"true"`/`"false"`. Consumers that parse metadata values as JSON booleans — which is common in cross-service tracing contexts like LangGraph — will see an unexpected capitalisation. Consider using a JSON-aware coercion for `bool` specifically.

```suggestion
            string_value = value if isinstance(value, str) else ("true" if value is True else "false" if value is False else str(value))
```

### Issue 3 of 3
tests/unit/test_propagate_attributes.py:489-492
Missing blank line between the previous test method and this new one; PEP 8 requires one blank line between methods in a class. There is also trailing whitespace at the end of the last `verify_span_attribute` block.

```suggestion
        self.verify_missing_attribute(
            child_span, f"{LangfuseOtelSpanAttributes.TRACE_METADATA}.invalid_key"
        )

    def test_metadata_coercion_of_non_string_values(self, langfuse_client, memory_exporter):
```

Reviews (1): Last reviewed commit: "fix(propagation): coerce non-string meta..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Allows propagate_attributes to accept and automatically convert non-string metadata values (int, float, bool) to strings instead of silently dropping them. This resolves tracing compatibility issues with LangGraph integrations.
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Aryan Srivastava seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

Comment thread langfuse/_client/propagation.py Outdated
@aryxnn aryxnn force-pushed the fix-metadata-coercion branch from 35139d4 to 1d1910f Compare May 31, 2026 22:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants