Skip to content

Fix ID-targeted state load dropping resources with regex-escaped filter values - #660

Open
michael-richey wants to merge 4 commits into
mainfrom
michael.richey/fix-idtargeted-exactmatch-unescape
Open

Fix ID-targeted state load dropping resources with regex-escaped filter values#660
michael-richey wants to merge 4 commits into
mainfrom
michael.richey/fix-idtargeted-exactmatch-unescape

Conversation

@michael-richey

@michael-richey michael-richey commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

Resources with regex-metacharacters in their ids (e.g. dotted log-metric names) could be silently dropped during a sync run when both --minimize-reads and Operator=ExactMatch Name=id filters are in use.

ExactMatch filter values are regex-escaped by callers (Go regexp.QuoteMeta, Python re.escape, etc.) so they match literally once wrapped in ^...$ and compiled — this is required, otherwise svc.request.count would also match svcXrequestYcount. The --minimize-reads ID-targeted fast path (extract_exact_id_filters_unwrap_exact_match_pattern) then reused the escaped pattern body as a literal storage key:

  • stored blob key: logs_metrics.svc.request.count.json, keyed inside by svc.request.count
  • looked-up key: svc\.request\.count ← never matches

State.get_by_ids / get_single returns None for the mismatch and skips it, so the resource never enters state.source, never reaches the dependency graph, and produces no create, no error, and no filtered outcome — it just disappears. Ids with no metacharacters were unaffected, which is why the failure was partial and easy to miss.

Fix

  • _unwrap_exact_match_pattern now un-escapes the ^...$ body back to the literal id via a new _regex_literal_from_exact_match_body helper.
  • If the body is not a provable literal — an unescaped metacharacter, a semantic or ambiguous alphanumeric escape such as \d, or a dangling backslash — it raises ValueError. extract_exact_id_filters already treats that as "not ID-targetable" and falls back to type-scoped loading, which matches via the compiled regex and stays correct.
  • Escaped punctuation and doubled backslashes are recovered as literal ID characters.
  • No behavior change for metacharacter-free ids (e.g. UUIDs): escaping is a no-op there.

Testing (red/green)

Added TestExactMatchEscapedValues in tests/unit/test_minimize_reads_id_targeted.py:

  • escaped dots are recovered as literal ID characters
  • plain literal IDs remain unchanged
  • doubled backslashes recover a literal backslash
  • genuine regex metacharacters trigger type-scoped fallback
  • semantic escapes such as \d trigger type-scoped fallback instead of targeting the wrong ID
  • escaped filters extract the original literal metric IDs
  • State.get_by_ids resolves an escaped-value ID against the real blob key

The escaped-ID regression tests fail on main and pass with the fix. The semantic-escape regression fails on the initial PR head by extracting literal ID d from a pattern that matches digits, then passes after the conservative fallback change.

Focused suite: 28 passed.

Unit suite excluding the pre-existing @pytest.mark.experiment_subprocess tests: 1100 passed, 8 skipped, 10 deselected.

michael-richey and others added 2 commits August 5, 2026 15:06
ExactMatch filter values are regex-escaped by callers (e.g. via
regexp.QuoteMeta or re.escape) so that metacharacters match literally
once the value is wrapped in ^...$ and compiled. The --minimize-reads
ID-targeted state load then reused the pattern body as a literal storage
key without reversing that escaping, so an id such as
"svc.request.count" was looked up as "svc\.request\.count" and never
matched its stored blob. Those resources were silently dropped from
state before diff/apply — no create, no error, no filtered count.

Un-escape the ExactMatch body back to the literal id in
_unwrap_exact_match_pattern. When the body is not a pure literal (an
unescaped metacharacter, i.e. a genuine regex, or a dangling backslash)
raise ValueError so extract_exact_id_filters falls back to type-scoped
loading, which matches via the compiled regex and stays correct.

Add red/green regression tests covering the unwrap helper and an
end-to-end escaped-value load through State.get_by_ids.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@michael-richey
michael-richey marked this pull request as ready for review August 5, 2026 19:25
@michael-richey
michael-richey requested a review from a team as a code owner August 5, 2026 19:25
@michael-richey
michael-richey requested a review from Copilot August 5, 2026 19:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes a --minimize-reads ID-targeted state loading bug where ExactMatch filters containing regex-escaped IDs (e.g., dotted metric IDs) could be treated as literal storage keys and silently fail to load matching resources.

Changes:

  • Add _regex_literal_from_exact_match_body and update _unwrap_exact_match_pattern to unescape regex-escaped ExactMatch bodies back to literal IDs, with a conservative ValueError fallback for non-literal patterns.
  • Add unit tests covering escaped dots, escaped backslashes, semantic escapes (e.g. \d), and an end-to-end State.get_by_ids resolution case.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
tests/unit/test_minimize_reads_id_targeted.py Adds regression/unit tests for escaped ExactMatch ID handling and ID-targeted state load behavior.
datadog_sync/utils/configuration.py Implements safe unescaping of ExactMatch regex bodies to recover literal IDs for ID-targeted loading.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread datadog_sync/utils/configuration.py
michael-richey and others added 2 commits August 5, 2026 15:33
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
A prior autofix commit rewrote the comment above this constant but
dropped the actual assignment, leaving the name referenced but
undefined and breaking ruff (F821).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants